diff --git a/app/src/main/java/net/nullsum/audinaut/activity/EditPlayActionActivity.java b/app/src/main/java/net/nullsum/audinaut/activity/EditPlayActionActivity.java index 8e42329..5cf4cc8 100644 --- a/app/src/main/java/net/nullsum/audinaut/activity/EditPlayActionActivity.java +++ b/app/src/main/java/net/nullsum/audinaut/activity/EditPlayActionActivity.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.activity; @@ -46,200 +46,200 @@ import net.nullsum.audinaut.util.LoadingTask; import net.nullsum.audinaut.util.Util; public class EditPlayActionActivity extends SubsonicActivity { - private CheckBox shuffleCheckbox; - private CheckBox startYearCheckbox; - private EditText startYearBox; - private CheckBox endYearCheckbox; - private EditText endYearBox; - private Button genreButton; - private Spinner offlineSpinner; - - private String doNothing; + private CheckBox shuffleCheckbox; + private CheckBox startYearCheckbox; + private EditText startYearBox; + private CheckBox endYearCheckbox; + private EditText endYearBox; + private Button genreButton; + private Spinner offlineSpinner; - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setTitle(R.string.tasker_start_playing_title); - setContentView(R.layout.edit_play_action); - final Activity context = this; - doNothing = context.getResources().getString(R.string.tasker_edit_do_nothing); + private String doNothing; - shuffleCheckbox = (CheckBox) findViewById(R.id.edit_shuffle_checkbox); - shuffleCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton view, boolean isChecked) { - startYearCheckbox.setEnabled(isChecked); - endYearCheckbox.setEnabled(isChecked); - genreButton.setEnabled(isChecked); - } - }); + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setTitle(R.string.tasker_start_playing_title); + setContentView(R.layout.edit_play_action); + final Activity context = this; + doNothing = context.getResources().getString(R.string.tasker_edit_do_nothing); - startYearCheckbox = (CheckBox) findViewById(R.id.edit_start_year_checkbox); - startYearBox = (EditText) findViewById(R.id.edit_start_year); - // Disable/enable number box if checked - startYearCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton view, boolean isChecked) { - startYearBox.setEnabled(isChecked); - } - }); - - endYearCheckbox = (CheckBox) findViewById(R.id.edit_end_year_checkbox); - endYearBox = (EditText) findViewById(R.id.edit_end_year); - endYearCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton view, boolean isChecked) { - endYearBox.setEnabled(isChecked); - } - }); + shuffleCheckbox = (CheckBox) findViewById(R.id.edit_shuffle_checkbox); + shuffleCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton view, boolean isChecked) { + startYearCheckbox.setEnabled(isChecked); + endYearCheckbox.setEnabled(isChecked); + genreButton.setEnabled(isChecked); + } + }); - genreButton = (Button) findViewById(R.id.edit_genre_spinner); - genreButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - new LoadingTask>(context, true) { - @Override - protected List doInBackground() throws Throwable { - MusicService musicService = MusicServiceFactory.getMusicService(context); - return musicService.getGenres(false, context, this); - } + startYearCheckbox = (CheckBox) findViewById(R.id.edit_start_year_checkbox); + startYearBox = (EditText) findViewById(R.id.edit_start_year); + // Disable/enable number box if checked + startYearCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton view, boolean isChecked) { + startYearBox.setEnabled(isChecked); + } + }); - @Override - protected void done(final List genres) { - List names = new ArrayList(); - String blank = context.getResources().getString(R.string.select_genre_blank); - names.add(doNothing); - names.add(blank); - for(Genre genre: genres) { - names.add(genre.getName()); - } - final List finalNames = names; + endYearCheckbox = (CheckBox) findViewById(R.id.edit_end_year_checkbox); + endYearBox = (EditText) findViewById(R.id.edit_end_year); + endYearCheckbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton view, boolean isChecked) { + endYearBox.setEnabled(isChecked); + } + }); - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.shuffle_pick_genre) - .setItems(names.toArray(new CharSequence[names.size()]), new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if(which == 1) { - genreButton.setText(""); - } else { - genreButton.setText(finalNames.get(which)); - } - } - }); - AlertDialog dialog = builder.create(); - dialog.show(); - } + genreButton = (Button) findViewById(R.id.edit_genre_spinner); + genreButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + new LoadingTask>(context, true) { + @Override + protected List doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + return musicService.getGenres(false, context, this); + } - @Override - protected void error(Throwable error) { - String msg; - if (error instanceof OfflineException) { - msg = getErrorMessage(error); - } else { - msg = context.getResources().getString(R.string.playlist_error) + " " + getErrorMessage(error); - } + @Override + protected void done(final List genres) { + List names = new ArrayList(); + String blank = context.getResources().getString(R.string.select_genre_blank); + names.add(doNothing); + names.add(blank); + for(Genre genre: genres) { + names.add(genre.getName()); + } + final List finalNames = names; - Util.toast(context, msg, false); - } - }.execute(); - } - }); - genreButton.setText(doNothing); + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.shuffle_pick_genre) + .setItems(names.toArray(new CharSequence[names.size()]), new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + if(which == 1) { + genreButton.setText(""); + } else { + genreButton.setText(finalNames.get(which)); + } + } + }); + AlertDialog dialog = builder.create(); + dialog.show(); + } - offlineSpinner = (Spinner) findViewById(R.id.edit_offline_spinner); - ArrayAdapter offlineAdapter = ArrayAdapter.createFromResource(this, R.array.editServerOptions, android.R.layout.simple_spinner_item); - offlineAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - offlineSpinner.setAdapter(offlineAdapter); - - // Setup default for everything - Bundle extras = getIntent().getBundleExtra(Constants.TASKER_EXTRA_BUNDLE); - if(extras != null) { - if(extras.getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE)) { - shuffleCheckbox.setChecked(true); - } - - String startYear = extras.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, null); - if(startYear != null) { - startYearCheckbox.setEnabled(true); - startYearBox.setText(startYear); - } - String endYear = extras.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, null); - if(endYear != null) { - endYearCheckbox.setEnabled(true); - endYearBox.setText(endYear); - } - - String genre = extras.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, doNothing); - if(genre != null) { - genreButton.setText(genre); - } - - int offline = extras.getInt(Constants.PREFERENCES_KEY_OFFLINE, 0); - if(offline != 0) { - offlineSpinner.setSelection(offline); - } - } + @Override + protected void error(Throwable error) { + String msg; + if (error instanceof OfflineException) { + msg = getErrorMessage(error); + } else { + msg = context.getResources().getString(R.string.playlist_error) + " " + getErrorMessage(error); + } - drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); - } + Util.toast(context, msg, false); + } + }.execute(); + } + }); + genreButton.setText(doNothing); - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater menuInflater = getMenuInflater(); - menuInflater.inflate(R.menu.tasker_configuration, menu); - return true; - } + offlineSpinner = (Spinner) findViewById(R.id.edit_offline_spinner); + ArrayAdapter offlineAdapter = ArrayAdapter.createFromResource(this, R.array.editServerOptions, android.R.layout.simple_spinner_item); + offlineAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + offlineSpinner.setAdapter(offlineAdapter); - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if(item.getItemId() == android.R.id.home) { - cancel(); - return true; - } else if(item.getItemId() == R.id.menu_accept) { - accept(); - return true; - } else if(item.getItemId() == R.id.menu_cancel) { - cancel(); - return true; - } + // Setup default for everything + Bundle extras = getIntent().getBundleExtra(Constants.TASKER_EXTRA_BUNDLE); + if(extras != null) { + if(extras.getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE)) { + shuffleCheckbox.setChecked(true); + } - return false; - } + String startYear = extras.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, null); + if(startYear != null) { + startYearCheckbox.setEnabled(true); + startYearBox.setText(startYear); + } + String endYear = extras.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, null); + if(endYear != null) { + endYearCheckbox.setEnabled(true); + endYearBox.setText(endYear); + } - private void accept() { - Intent intent = new Intent(); + String genre = extras.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, doNothing); + if(genre != null) { + genreButton.setText(genre); + } - String blurb = getResources().getString(shuffleCheckbox.isChecked() ? R.string.tasker_start_playing_shuffled : R.string.tasker_start_playing); - intent.putExtra("com.twofortyfouram.locale.intent.extra.BLURB", blurb); + int offline = extras.getInt(Constants.PREFERENCES_KEY_OFFLINE, 0); + if(offline != 0) { + offlineSpinner.setSelection(offline); + } + } - // Get settings user specified - Bundle data = new Bundle(); - boolean shuffle = shuffleCheckbox.isChecked(); - data.putBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, shuffle); - if(shuffle) { - if(startYearCheckbox.isChecked()) { - data.putString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, startYearBox.getText().toString()); - } - if(endYearCheckbox.isChecked()) { - data.putString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, endYearBox.getText().toString()); - } - String genre = genreButton.getText().toString(); - if(!genre.equals(doNothing)) { - data.putString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, genre); - } - } - - int offline = offlineSpinner.getSelectedItemPosition(); - if(offline != 0) { - data.putInt(Constants.PREFERENCES_KEY_OFFLINE, offline); - } - - intent.putExtra(Constants.TASKER_EXTRA_BUNDLE, data); + drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED); + } - setResult(Activity.RESULT_OK, intent); - finish(); - } - private void cancel() { - setResult(Activity.RESULT_CANCELED); - finish(); - } + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater menuInflater = getMenuInflater(); + menuInflater.inflate(R.menu.tasker_configuration, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if(item.getItemId() == android.R.id.home) { + cancel(); + return true; + } else if(item.getItemId() == R.id.menu_accept) { + accept(); + return true; + } else if(item.getItemId() == R.id.menu_cancel) { + cancel(); + return true; + } + + return false; + } + + private void accept() { + Intent intent = new Intent(); + + String blurb = getResources().getString(shuffleCheckbox.isChecked() ? R.string.tasker_start_playing_shuffled : R.string.tasker_start_playing); + intent.putExtra("com.twofortyfouram.locale.intent.extra.BLURB", blurb); + + // Get settings user specified + Bundle data = new Bundle(); + boolean shuffle = shuffleCheckbox.isChecked(); + data.putBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, shuffle); + if(shuffle) { + if(startYearCheckbox.isChecked()) { + data.putString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, startYearBox.getText().toString()); + } + if(endYearCheckbox.isChecked()) { + data.putString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, endYearBox.getText().toString()); + } + String genre = genreButton.getText().toString(); + if(!genre.equals(doNothing)) { + data.putString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, genre); + } + } + + int offline = offlineSpinner.getSelectedItemPosition(); + if(offline != 0) { + data.putInt(Constants.PREFERENCES_KEY_OFFLINE, offline); + } + + intent.putExtra(Constants.TASKER_EXTRA_BUNDLE, data); + + setResult(Activity.RESULT_OK, intent); + finish(); + } + private void cancel() { + setResult(Activity.RESULT_CANCELED); + finish(); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/activity/QueryReceiverActivity.java b/app/src/main/java/net/nullsum/audinaut/activity/QueryReceiverActivity.java index cb627bb..e4107e9 100644 --- a/app/src/main/java/net/nullsum/audinaut/activity/QueryReceiverActivity.java +++ b/app/src/main/java/net/nullsum/audinaut/activity/QueryReceiverActivity.java @@ -38,48 +38,48 @@ import net.nullsum.audinaut.provider.AudinautSearchProvider; */ public class QueryReceiverActivity extends Activity { - private static final String TAG = QueryReceiverActivity.class.getSimpleName(); + private static final String TAG = QueryReceiverActivity.class.getSimpleName(); - @Override + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Intent intent = getIntent(); - if (Intent.ACTION_SEARCH.equals(intent.getAction())) { - doSearch(); - } else if(Intent.ACTION_VIEW.equals(intent.getAction())) { - showResult(intent.getDataString(), intent.getStringExtra(SearchManager.EXTRA_DATA_KEY)); - } + Intent intent = getIntent(); + if (Intent.ACTION_SEARCH.equals(intent.getAction())) { + doSearch(); + } else if(Intent.ACTION_VIEW.equals(intent.getAction())) { + showResult(intent.getDataString(), intent.getStringExtra(SearchManager.EXTRA_DATA_KEY)); + } finish(); Util.disablePendingTransition(this); } - private void doSearch() { - String query = getIntent().getStringExtra(SearchManager.QUERY); - if (query != null) { - Intent intent = new Intent(QueryReceiverActivity.this, SubsonicFragmentActivity.class); - intent.putExtra(Constants.INTENT_EXTRA_NAME_QUERY, query); - intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); - Util.startActivityWithoutTransition(QueryReceiverActivity.this, intent); - } - } - private void showResult(String albumId, String name) { - if (albumId != null) { - Intent intent = new Intent(this, SubsonicFragmentActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); - intent.putExtra(Constants.INTENT_EXTRA_VIEW_ALBUM, true); - if(albumId.indexOf("ar-") == 0) { - intent.putExtra(Constants.INTENT_EXTRA_NAME_ARTIST, true); - albumId = albumId.replace("ar-", ""); - } else if(albumId.indexOf("so-") == 0) { - intent.putExtra(Constants.INTENT_EXTRA_SEARCH_SONG, name); - albumId = albumId.replace("so-", ""); - } - intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, albumId); - if (name != null) { - intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, name); - } - Util.startActivityWithoutTransition(this, intent); - } - } + private void doSearch() { + String query = getIntent().getStringExtra(SearchManager.QUERY); + if (query != null) { + Intent intent = new Intent(QueryReceiverActivity.this, SubsonicFragmentActivity.class); + intent.putExtra(Constants.INTENT_EXTRA_NAME_QUERY, query); + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); + Util.startActivityWithoutTransition(QueryReceiverActivity.this, intent); + } + } + private void showResult(String albumId, String name) { + if (albumId != null) { + Intent intent = new Intent(this, SubsonicFragmentActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); + intent.putExtra(Constants.INTENT_EXTRA_VIEW_ALBUM, true); + if(albumId.indexOf("ar-") == 0) { + intent.putExtra(Constants.INTENT_EXTRA_NAME_ARTIST, true); + albumId = albumId.replace("ar-", ""); + } else if(albumId.indexOf("so-") == 0) { + intent.putExtra(Constants.INTENT_EXTRA_SEARCH_SONG, name); + albumId = albumId.replace("so-", ""); + } + intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, albumId); + if (name != null) { + intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, name); + } + Util.startActivityWithoutTransition(this, intent); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/activity/SettingsActivity.java b/app/src/main/java/net/nullsum/audinaut/activity/SettingsActivity.java index b459b9a..399e80c 100644 --- a/app/src/main/java/net/nullsum/audinaut/activity/SettingsActivity.java +++ b/app/src/main/java/net/nullsum/audinaut/activity/SettingsActivity.java @@ -28,29 +28,29 @@ import net.nullsum.audinaut.fragments.SettingsFragment; import net.nullsum.audinaut.util.Constants; public class SettingsActivity extends SubsonicActivity { - private static final String TAG = SettingsActivity.class.getSimpleName(); - private PreferenceCompatFragment fragment; + private static final String TAG = SettingsActivity.class.getSimpleName(); + private PreferenceCompatFragment fragment; - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - lastSelectedPosition = R.id.drawer_settings; - setContentView(R.layout.settings_activity); + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + lastSelectedPosition = R.id.drawer_settings; + setContentView(R.layout.settings_activity); - if (savedInstanceState == null) { - fragment = new SettingsFragment(); - Bundle args = new Bundle(); - args.putInt(Constants.INTENT_EXTRA_FRAGMENT_TYPE, R.xml.settings); + if (savedInstanceState == null) { + fragment = new SettingsFragment(); + Bundle args = new Bundle(); + args.putInt(Constants.INTENT_EXTRA_FRAGMENT_TYPE, R.xml.settings); - fragment.setArguments(args); - fragment.setRetainInstance(true); + fragment.setArguments(args); + fragment.setRetainInstance(true); - currentFragment = fragment; - currentFragment.setPrimaryFragment(true); - getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, currentFragment, currentFragment.getSupportTag() + "").commit(); - } + currentFragment = fragment; + currentFragment.setPrimaryFragment(true); + getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, currentFragment, currentFragment.getSupportTag() + "").commit(); + } - Toolbar mainToolbar = (Toolbar) findViewById(R.id.main_toolbar); - setSupportActionBar(mainToolbar); - } + Toolbar mainToolbar = (Toolbar) findViewById(R.id.main_toolbar); + setSupportActionBar(mainToolbar); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/activity/SubsonicActivity.java b/app/src/main/java/net/nullsum/audinaut/activity/SubsonicActivity.java index 7d9913b..672c595 100644 --- a/app/src/main/java/net/nullsum/audinaut/activity/SubsonicActivity.java +++ b/app/src/main/java/net/nullsum/audinaut/activity/SubsonicActivity.java @@ -85,222 +85,222 @@ import net.nullsum.audinaut.util.UserUtil; import static android.Manifest.*; public class SubsonicActivity extends AppCompatActivity implements OnItemSelectedListener { - private static final String TAG = SubsonicActivity.class.getSimpleName(); - private static ImageLoader IMAGE_LOADER; - protected static String theme; - protected static boolean fullScreen; - protected static boolean actionbarColored; - private static final int MENU_GROUP_SERVER = 10; - private static final int MENU_ITEM_SERVER_BASE = 100; - private static final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1; + private static final String TAG = SubsonicActivity.class.getSimpleName(); + private static ImageLoader IMAGE_LOADER; + protected static String theme; + protected static boolean fullScreen; + protected static boolean actionbarColored; + private static final int MENU_GROUP_SERVER = 10; + private static final int MENU_ITEM_SERVER_BASE = 100; + private static final int PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1; - private final List afterServiceAvailable = new ArrayList<>(); - private boolean drawerIdle = true; - private boolean destroyed = false; - private boolean finished = false; - protected List backStack = new ArrayList(); - protected SubsonicFragment currentFragment; - protected View primaryContainer; - protected View secondaryContainer; - protected boolean touchscreen = true; - protected Handler handler = new Handler(); - Spinner actionBarSpinner; - ArrayAdapter spinnerAdapter; - ViewGroup rootView; - DrawerLayout drawer; - ActionBarDrawerToggle drawerToggle; - NavigationView drawerList; - View drawerHeader; - ImageView drawerHeaderToggle; - TextView drawerServerName; - TextView drawerUserName; - int lastSelectedPosition = 0; - boolean showingTabs = true; - boolean drawerOpen = false; - SharedPreferences.OnSharedPreferenceChangeListener preferencesListener; + private final List afterServiceAvailable = new ArrayList<>(); + private boolean drawerIdle = true; + private boolean destroyed = false; + private boolean finished = false; + protected List backStack = new ArrayList(); + protected SubsonicFragment currentFragment; + protected View primaryContainer; + protected View secondaryContainer; + protected boolean touchscreen = true; + protected Handler handler = new Handler(); + Spinner actionBarSpinner; + ArrayAdapter spinnerAdapter; + ViewGroup rootView; + DrawerLayout drawer; + ActionBarDrawerToggle drawerToggle; + NavigationView drawerList; + View drawerHeader; + ImageView drawerHeaderToggle; + TextView drawerServerName; + TextView drawerUserName; + int lastSelectedPosition = 0; + boolean showingTabs = true; + boolean drawerOpen = false; + SharedPreferences.OnSharedPreferenceChangeListener preferencesListener; - static { - AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO); - } + static { + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO); + } - @Override - protected void onCreate(Bundle bundle) { - UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE); - PackageManager pm = getPackageManager(); - if(!pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) { - touchscreen = false; - } + @Override + protected void onCreate(Bundle bundle) { + UiModeManager uiModeManager = (UiModeManager) getSystemService(UI_MODE_SERVICE); + PackageManager pm = getPackageManager(); + if(!pm.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN)) { + touchscreen = false; + } - setUncaughtExceptionHandler(); - applyTheme(); - applyFullscreen(); - super.onCreate(bundle); - startService(new Intent(this, DownloadService.class)); - setVolumeControlStream(AudioManager.STREAM_MUSIC); + setUncaughtExceptionHandler(); + applyTheme(); + applyFullscreen(); + super.onCreate(bundle); + startService(new Intent(this, DownloadService.class)); + setVolumeControlStream(AudioManager.STREAM_MUSIC); - if(getIntent().hasExtra(Constants.FRAGMENT_POSITION)) { - lastSelectedPosition = getIntent().getIntExtra(Constants.FRAGMENT_POSITION, 0); - } + if(getIntent().hasExtra(Constants.FRAGMENT_POSITION)) { + lastSelectedPosition = getIntent().getIntExtra(Constants.FRAGMENT_POSITION, 0); + } - if(preferencesListener == null) { - Util.getPreferences(this).registerOnSharedPreferenceChangeListener(preferencesListener); - } + if(preferencesListener == null) { + Util.getPreferences(this).registerOnSharedPreferenceChangeListener(preferencesListener); + } - if (ContextCompat.checkSelfPermission(this, permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { - ActivityCompat.requestPermissions(this, new String[]{ permission.WRITE_EXTERNAL_STORAGE }, PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE); - } - } + if (ContextCompat.checkSelfPermission(this, permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, new String[]{ permission.WRITE_EXTERNAL_STORAGE }, PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE); + } + } - @Override - public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { - switch (requestCode) { - case PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: { - // If request is cancelled, the result arrays are empty. - if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + @Override + public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { + switch (requestCode) { + case PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: { + // If request is cancelled, the result arrays are empty. + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { - } else { - Util.toast(this, R.string.permission_external_storage_failed); - finish(); - } - } - } - } + } else { + Util.toast(this, R.string.permission_external_storage_failed); + finish(); + } + } + } + } - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); + @Override + protected void onPostCreate(Bundle savedInstanceState) { + super.onPostCreate(savedInstanceState); - if(spinnerAdapter == null) { - createCustomActionBarView(); - } - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - getSupportActionBar().setHomeButtonEnabled(true); + if(spinnerAdapter == null) { + createCustomActionBarView(); + } + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeButtonEnabled(true); - if(Util.shouldStartOnHeadphones(this)) { - Intent serviceIntent = new Intent(); - serviceIntent.setClassName(this.getPackageName(), HeadphoneListenerService.class.getName()); - this.startService(serviceIntent); - } - } + if(Util.shouldStartOnHeadphones(this)) { + Intent serviceIntent = new Intent(); + serviceIntent.setClassName(this.getPackageName(), HeadphoneListenerService.class.getName()); + this.startService(serviceIntent); + } + } - protected void createCustomActionBarView() { - actionBarSpinner = (Spinner) getLayoutInflater().inflate(R.layout.actionbar_spinner, null); - if((this instanceof SubsonicFragmentActivity || this instanceof SettingsActivity) && (Util.getPreferences(this).getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true) || ThemeUtil.getThemeRes(this) != R.style.Theme_Audinaut_Light_No_Color)) { - actionBarSpinner.setBackgroundDrawable(DrawableTint.getTintedDrawableFromColor(this, R.drawable.abc_spinner_mtrl_am_alpha, android.R.color.white)); - } - spinnerAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item); - spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); - actionBarSpinner.setOnItemSelectedListener(this); - actionBarSpinner.setAdapter(spinnerAdapter); + protected void createCustomActionBarView() { + actionBarSpinner = (Spinner) getLayoutInflater().inflate(R.layout.actionbar_spinner, null); + if((this instanceof SubsonicFragmentActivity || this instanceof SettingsActivity) && (Util.getPreferences(this).getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true) || ThemeUtil.getThemeRes(this) != R.style.Theme_Audinaut_Light_No_Color)) { + actionBarSpinner.setBackgroundDrawable(DrawableTint.getTintedDrawableFromColor(this, R.drawable.abc_spinner_mtrl_am_alpha, android.R.color.white)); + } + spinnerAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item); + spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + actionBarSpinner.setOnItemSelectedListener(this); + actionBarSpinner.setAdapter(spinnerAdapter); - getSupportActionBar().setCustomView(actionBarSpinner); - } + getSupportActionBar().setCustomView(actionBarSpinner); + } - @Override - protected void onResume() { - super.onResume(); - Util.registerMediaButtonEventReceiver(this); + @Override + protected void onResume() { + super.onResume(); + Util.registerMediaButtonEventReceiver(this); - // Make sure to update theme - SharedPreferences prefs = Util.getPreferences(this); - if (theme != null && !theme.equals(ThemeUtil.getTheme(this)) || fullScreen != prefs.getBoolean(Constants.PREFERENCES_KEY_FULL_SCREEN, false) || actionbarColored != prefs.getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true)) { - restart(); - overridePendingTransition(R.anim.fade_in, R.anim.fade_out); - DrawableTint.wipeTintCache(); - } + // Make sure to update theme + SharedPreferences prefs = Util.getPreferences(this); + if (theme != null && !theme.equals(ThemeUtil.getTheme(this)) || fullScreen != prefs.getBoolean(Constants.PREFERENCES_KEY_FULL_SCREEN, false) || actionbarColored != prefs.getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true)) { + restart(); + overridePendingTransition(R.anim.fade_in, R.anim.fade_out); + DrawableTint.wipeTintCache(); + } - populateTabs(); - getImageLoader().onUIVisible(); - UpdateView.addActiveActivity(); - } + populateTabs(); + getImageLoader().onUIVisible(); + UpdateView.addActiveActivity(); + } - @Override - protected void onPause() { - super.onPause(); + @Override + protected void onPause() { + super.onPause(); - UpdateView.removeActiveActivity(); - } + UpdateView.removeActiveActivity(); + } - @Override - protected void onDestroy() { - super.onDestroy(); - destroyed = true; - Util.getPreferences(this).unregisterOnSharedPreferenceChangeListener(preferencesListener); - } + @Override + protected void onDestroy() { + super.onDestroy(); + destroyed = true; + Util.getPreferences(this).unregisterOnSharedPreferenceChangeListener(preferencesListener); + } - @Override - public void finish() { - super.finish(); - Util.disablePendingTransition(this); - } + @Override + public void finish() { + super.finish(); + Util.disablePendingTransition(this); + } - @Override - public void setContentView(int viewId) { + @Override + public void setContentView(int viewId) { super.setContentView(R.layout.abstract_activity); - rootView = (ViewGroup) findViewById(R.id.content_frame); + rootView = (ViewGroup) findViewById(R.id.content_frame); - if(viewId != 0) { - LayoutInflater layoutInflater = getLayoutInflater(); - layoutInflater.inflate(viewId, rootView); - } + if(viewId != 0) { + LayoutInflater layoutInflater = getLayoutInflater(); + layoutInflater.inflate(viewId, rootView); + } - drawerList = (NavigationView) findViewById(R.id.left_drawer); - drawerList.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { - @Override - public boolean onNavigationItemSelected(final MenuItem menuItem) { - if(showingTabs) { - // Settings are on a different selectable track - if (menuItem.getItemId() != R.id.drawer_settings && menuItem.getItemId() != R.id.drawer_offline) { - menuItem.setChecked(true); - lastSelectedPosition = menuItem.getItemId(); - } + drawerList = (NavigationView) findViewById(R.id.left_drawer); + drawerList.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(final MenuItem menuItem) { + if(showingTabs) { + // Settings are on a different selectable track + if (menuItem.getItemId() != R.id.drawer_settings && menuItem.getItemId() != R.id.drawer_offline) { + menuItem.setChecked(true); + lastSelectedPosition = menuItem.getItemId(); + } - switch (menuItem.getItemId()) { - case R.id.drawer_library: - drawerItemSelected("Artist"); - return true; - case R.id.drawer_playlists: - drawerItemSelected("Playlist"); - return true; - case R.id.drawer_downloading: - drawerItemSelected("Download"); - return true; - case R.id.drawer_offline: - toggleOffline(); - return true; - case R.id.drawer_settings: - startActivity(new Intent(SubsonicActivity.this, SettingsActivity.class)); - drawer.closeDrawers(); - return true; - } - } else { - int activeServer = menuItem.getItemId() - MENU_ITEM_SERVER_BASE; - SubsonicActivity.this.setActiveServer(activeServer); - populateTabs(); - return true; - } + switch (menuItem.getItemId()) { + case R.id.drawer_library: + drawerItemSelected("Artist"); + return true; + case R.id.drawer_playlists: + drawerItemSelected("Playlist"); + return true; + case R.id.drawer_downloading: + drawerItemSelected("Download"); + return true; + case R.id.drawer_offline: + toggleOffline(); + return true; + case R.id.drawer_settings: + startActivity(new Intent(SubsonicActivity.this, SettingsActivity.class)); + drawer.closeDrawers(); + return true; + } + } else { + int activeServer = menuItem.getItemId() - MENU_ITEM_SERVER_BASE; + SubsonicActivity.this.setActiveServer(activeServer); + populateTabs(); + return true; + } - return false; - } - }); + return false; + } + }); - drawerHeader = drawerList.inflateHeaderView(R.layout.drawer_header); - drawerHeader.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if(showingTabs) { - populateServers(); - } else { - populateTabs(); - } - } - }); + drawerHeader = drawerList.inflateHeaderView(R.layout.drawer_header); + drawerHeader.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if(showingTabs) { + populateServers(); + } else { + populateTabs(); + } + } + }); - drawerHeaderToggle = (ImageView) drawerHeader.findViewById(R.id.header_select_image); - drawerServerName = (TextView) drawerHeader.findViewById(R.id.header_server_name); - drawerUserName = (TextView) drawerHeader.findViewById(R.id.header_user_name); + drawerHeaderToggle = (ImageView) drawerHeader.findViewById(R.id.header_select_image); + drawerServerName = (TextView) drawerHeader.findViewById(R.id.header_server_name); + drawerUserName = (TextView) drawerHeader.findViewById(R.id.header_user_name); - updateDrawerHeader(); + updateDrawerHeader(); drawer = (DrawerLayout) findViewById(R.id.drawer_layout); @@ -349,685 +349,685 @@ public class SubsonicActivity extends AppCompatActivity implements OnItemSelecte } }); - // Check whether this is a tablet or not - secondaryContainer = findViewById(R.id.fragment_second_container); - if(secondaryContainer != null) { - primaryContainer = findViewById(R.id.fragment_container); - } - } + // Check whether this is a tablet or not + secondaryContainer = findViewById(R.id.fragment_second_container); + if(secondaryContainer != null) { + primaryContainer = findViewById(R.id.fragment_container); + } + } - @Override - public void onSaveInstanceState(Bundle savedInstanceState) { - super.onSaveInstanceState(savedInstanceState); - String[] ids = new String[backStack.size() + 1]; - ids[0] = currentFragment.getTag(); - int i = 1; - for(SubsonicFragment frag: backStack) { - ids[i] = frag.getTag(); - i++; - } - savedInstanceState.putStringArray(Constants.MAIN_BACK_STACK, ids); - savedInstanceState.putInt(Constants.MAIN_BACK_STACK_SIZE, backStack.size() + 1); - savedInstanceState.putInt(Constants.FRAGMENT_POSITION, lastSelectedPosition); - } - @Override - public void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); - int size = savedInstanceState.getInt(Constants.MAIN_BACK_STACK_SIZE); - String[] ids = savedInstanceState.getStringArray(Constants.MAIN_BACK_STACK); - FragmentManager fm = getSupportFragmentManager(); - currentFragment = (SubsonicFragment)fm.findFragmentByTag(ids[0]); - currentFragment.setPrimaryFragment(true); - currentFragment.setSupportTag(ids[0]); - supportInvalidateOptionsMenu(); - FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); - for(int i = 1; i < size; i++) { - SubsonicFragment frag = (SubsonicFragment)fm.findFragmentByTag(ids[i]); - frag.setSupportTag(ids[i]); - if(secondaryContainer != null) { - frag.setPrimaryFragment(false, true); - } - trans.hide(frag); - backStack.add(frag); - } - trans.commit(); + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + super.onSaveInstanceState(savedInstanceState); + String[] ids = new String[backStack.size() + 1]; + ids[0] = currentFragment.getTag(); + int i = 1; + for(SubsonicFragment frag: backStack) { + ids[i] = frag.getTag(); + i++; + } + savedInstanceState.putStringArray(Constants.MAIN_BACK_STACK, ids); + savedInstanceState.putInt(Constants.MAIN_BACK_STACK_SIZE, backStack.size() + 1); + savedInstanceState.putInt(Constants.FRAGMENT_POSITION, lastSelectedPosition); + } + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); + int size = savedInstanceState.getInt(Constants.MAIN_BACK_STACK_SIZE); + String[] ids = savedInstanceState.getStringArray(Constants.MAIN_BACK_STACK); + FragmentManager fm = getSupportFragmentManager(); + currentFragment = (SubsonicFragment)fm.findFragmentByTag(ids[0]); + currentFragment.setPrimaryFragment(true); + currentFragment.setSupportTag(ids[0]); + supportInvalidateOptionsMenu(); + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); + for(int i = 1; i < size; i++) { + SubsonicFragment frag = (SubsonicFragment)fm.findFragmentByTag(ids[i]); + frag.setSupportTag(ids[i]); + if(secondaryContainer != null) { + frag.setPrimaryFragment(false, true); + } + trans.hide(frag); + backStack.add(frag); + } + trans.commit(); - // Current fragment is hidden in secondaryContainer - if(secondaryContainer == null && !currentFragment.isVisible()) { - trans = getSupportFragmentManager().beginTransaction(); - trans.remove(currentFragment); - trans.commit(); - getSupportFragmentManager().executePendingTransactions(); + // Current fragment is hidden in secondaryContainer + if(secondaryContainer == null && !currentFragment.isVisible()) { + trans = getSupportFragmentManager().beginTransaction(); + trans.remove(currentFragment); + trans.commit(); + getSupportFragmentManager().executePendingTransactions(); - trans = getSupportFragmentManager().beginTransaction(); - trans.add(R.id.fragment_container, currentFragment, ids[0]); - trans.commit(); - } - // Current fragment needs to be moved over to secondaryContainer - else if(secondaryContainer != null && secondaryContainer.findViewById(currentFragment.getRootId()) == null && backStack.size() > 0) { - trans = getSupportFragmentManager().beginTransaction(); - trans.remove(currentFragment); - trans.show(backStack.get(backStack.size() - 1)); - trans.commit(); - getSupportFragmentManager().executePendingTransactions(); + trans = getSupportFragmentManager().beginTransaction(); + trans.add(R.id.fragment_container, currentFragment, ids[0]); + trans.commit(); + } + // Current fragment needs to be moved over to secondaryContainer + else if(secondaryContainer != null && secondaryContainer.findViewById(currentFragment.getRootId()) == null && backStack.size() > 0) { + trans = getSupportFragmentManager().beginTransaction(); + trans.remove(currentFragment); + trans.show(backStack.get(backStack.size() - 1)); + trans.commit(); + getSupportFragmentManager().executePendingTransactions(); - trans = getSupportFragmentManager().beginTransaction(); - trans.add(R.id.fragment_second_container, currentFragment, ids[0]); - trans.commit(); + trans = getSupportFragmentManager().beginTransaction(); + trans.add(R.id.fragment_second_container, currentFragment, ids[0]); + trans.commit(); - secondaryContainer.setVisibility(View.VISIBLE); - } + secondaryContainer.setVisibility(View.VISIBLE); + } - lastSelectedPosition = savedInstanceState.getInt(Constants.FRAGMENT_POSITION); - if(lastSelectedPosition != 0) { - MenuItem item = drawerList.getMenu().findItem(lastSelectedPosition); - if(item != null) { - item.setChecked(true); - } - } - recreateSpinner(); - } + lastSelectedPosition = savedInstanceState.getInt(Constants.FRAGMENT_POSITION); + if(lastSelectedPosition != 0) { + MenuItem item = drawerList.getMenu().findItem(lastSelectedPosition); + if(item != null) { + item.setChecked(true); + } + } + recreateSpinner(); + } - @Override - public void onNewIntent(Intent intent) { - super.onNewIntent(intent); - } + @Override + public void onNewIntent(Intent intent) { + super.onNewIntent(intent); + } - @Override - public boolean onCreateOptionsMenu(Menu menu) { - MenuInflater menuInflater = getMenuInflater(); - SubsonicFragment currentFragment = getCurrentFragment(); - if(currentFragment != null) { - try { - SubsonicFragment fragment = getCurrentFragment(); - fragment.setContext(this); - fragment.onCreateOptionsMenu(menu, menuInflater); + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater menuInflater = getMenuInflater(); + SubsonicFragment currentFragment = getCurrentFragment(); + if(currentFragment != null) { + try { + SubsonicFragment fragment = getCurrentFragment(); + fragment.setContext(this); + fragment.onCreateOptionsMenu(menu, menuInflater); - if(isTouchscreen()) { - menu.setGroupVisible(R.id.not_touchscreen, false); - } - } catch(Exception e) { - Log.w(TAG, "Error on creating options menu", e); - } - } - return true; - } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if(drawerToggle != null && drawerToggle.onOptionsItemSelected(item)) { - return true; - } else if(item.getItemId() == android.R.id.home) { - onBackPressed(); - return true; - } + if(isTouchscreen()) { + menu.setGroupVisible(R.id.not_touchscreen, false); + } + } catch(Exception e) { + Log.w(TAG, "Error on creating options menu", e); + } + } + return true; + } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if(drawerToggle != null && drawerToggle.onOptionsItemSelected(item)) { + return true; + } else if(item.getItemId() == android.R.id.home) { + onBackPressed(); + return true; + } - return getCurrentFragment().onOptionsItemSelected(item); - } + return getCurrentFragment().onOptionsItemSelected(item); + } - @Override - public boolean onKeyDown(int keyCode, KeyEvent event) { - boolean isVolumeDown = keyCode == KeyEvent.KEYCODE_VOLUME_DOWN; - boolean isVolumeUp = keyCode == KeyEvent.KEYCODE_VOLUME_UP; - boolean isVolumeAdjust = isVolumeDown || isVolumeUp; + @Override + public boolean onKeyDown(int keyCode, KeyEvent event) { + boolean isVolumeDown = keyCode == KeyEvent.KEYCODE_VOLUME_DOWN; + boolean isVolumeUp = keyCode == KeyEvent.KEYCODE_VOLUME_UP; + boolean isVolumeAdjust = isVolumeDown || isVolumeUp; - return super.onKeyDown(keyCode, event); - } + return super.onKeyDown(keyCode, event); + } - @Override - public void setTitle(CharSequence title) { - if(title != null && getSupportActionBar() != null && !title.equals(getSupportActionBar().getTitle())) { - getSupportActionBar().setTitle(title); - recreateSpinner(); - } - } - public void setSubtitle(CharSequence title) { - getSupportActionBar().setSubtitle(title); - } + @Override + public void setTitle(CharSequence title) { + if(title != null && getSupportActionBar() != null && !title.equals(getSupportActionBar().getTitle())) { + getSupportActionBar().setTitle(title); + recreateSpinner(); + } + } + public void setSubtitle(CharSequence title) { + getSupportActionBar().setSubtitle(title); + } - @Override - public void onItemSelected(AdapterView parent, View view, int position, long id) { - int top = spinnerAdapter.getCount() - 1; - if(position < top) { - for(int i = top; i > position && i >= 0; i--) { - removeCurrent(); - } - } - } + @Override + public void onItemSelected(AdapterView parent, View view, int position, long id) { + int top = spinnerAdapter.getCount() - 1; + if(position < top) { + for(int i = top; i > position && i >= 0; i--) { + removeCurrent(); + } + } + } - @Override - public void onNothingSelected(AdapterView parent) { + @Override + public void onNothingSelected(AdapterView parent) { - } + } - private void populateTabs() { - drawerList.getMenu().clear(); - drawerList.inflateMenu(R.menu.drawer_navigation); + private void populateTabs() { + drawerList.getMenu().clear(); + drawerList.inflateMenu(R.menu.drawer_navigation); - SharedPreferences prefs = Util.getPreferences(this); - boolean sharedEnabled = prefs.getBoolean(Constants.PREFERENCES_KEY_SHARED_ENABLED, true) && !Util.isOffline(this); + SharedPreferences prefs = Util.getPreferences(this); + boolean sharedEnabled = prefs.getBoolean(Constants.PREFERENCES_KEY_SHARED_ENABLED, true) && !Util.isOffline(this); - MenuItem offlineMenuItem = drawerList.getMenu().findItem(R.id.drawer_offline); - if(Util.isOffline(this)) { - if(lastSelectedPosition == 0 || lastSelectedPosition == R.id.drawer_library) { - String newFragment = Util.openToTab(this); - if(newFragment == null || "Library".equals(newFragment)) { - newFragment = "Artist"; - } + MenuItem offlineMenuItem = drawerList.getMenu().findItem(R.id.drawer_offline); + if(Util.isOffline(this)) { + if(lastSelectedPosition == 0 || lastSelectedPosition == R.id.drawer_library) { + String newFragment = Util.openToTab(this); + if(newFragment == null || "Library".equals(newFragment)) { + newFragment = "Artist"; + } - lastSelectedPosition = getDrawerItemId(newFragment); - drawerItemSelected(newFragment); - } + lastSelectedPosition = getDrawerItemId(newFragment); + drawerItemSelected(newFragment); + } - offlineMenuItem.setTitle(R.string.main_online); - } else { - offlineMenuItem.setTitle(R.string.main_offline); - } + offlineMenuItem.setTitle(R.string.main_online); + } else { + offlineMenuItem.setTitle(R.string.main_offline); + } - if(lastSelectedPosition != 0) { - MenuItem item = drawerList.getMenu().findItem(lastSelectedPosition); - if(item != null) { - item.setChecked(true); - } - } - drawerHeaderToggle.setImageResource(R.drawable.main_select_server_dark); + if(lastSelectedPosition != 0) { + MenuItem item = drawerList.getMenu().findItem(lastSelectedPosition); + if(item != null) { + item.setChecked(true); + } + } + drawerHeaderToggle.setImageResource(R.drawable.main_select_server_dark); - showingTabs = true; - } - private void populateServers() { - drawerList.getMenu().clear(); + showingTabs = true; + } + private void populateServers() { + drawerList.getMenu().clear(); - int serverCount = Util.getServerCount(this); - int activeServer = Util.getActiveServer(this); - for(int i = 1; i <= serverCount; i++) { - MenuItem item = drawerList.getMenu().add(MENU_GROUP_SERVER, MENU_ITEM_SERVER_BASE + i, MENU_ITEM_SERVER_BASE + i, Util.getServerName(this, i)); - if(activeServer == i) { - item.setChecked(true); - } - } - drawerList.getMenu().setGroupCheckable(MENU_GROUP_SERVER, true, true); - drawerHeaderToggle.setImageResource(R.drawable.main_select_tabs_dark); + int serverCount = Util.getServerCount(this); + int activeServer = Util.getActiveServer(this); + for(int i = 1; i <= serverCount; i++) { + MenuItem item = drawerList.getMenu().add(MENU_GROUP_SERVER, MENU_ITEM_SERVER_BASE + i, MENU_ITEM_SERVER_BASE + i, Util.getServerName(this, i)); + if(activeServer == i) { + item.setChecked(true); + } + } + drawerList.getMenu().setGroupCheckable(MENU_GROUP_SERVER, true, true); + drawerHeaderToggle.setImageResource(R.drawable.main_select_tabs_dark); - showingTabs = false; - } - private void setDrawerItemVisible(int id, boolean visible) { - MenuItem item = drawerList.getMenu().findItem(id); - if(item != null) { - item.setVisible(visible); - } - } + showingTabs = false; + } + private void setDrawerItemVisible(int id, boolean visible) { + MenuItem item = drawerList.getMenu().findItem(id); + if(item != null) { + item.setVisible(visible); + } + } - protected void drawerItemSelected(String fragmentType) { - if(currentFragment != null) { - currentFragment.stopActionMode(); - } - startFragmentActivity(fragmentType); - } + protected void drawerItemSelected(String fragmentType) { + if(currentFragment != null) { + currentFragment.stopActionMode(); + } + startFragmentActivity(fragmentType); + } - public void startFragmentActivity(String fragmentType) { - Intent intent = new Intent(); - intent.setClass(SubsonicActivity.this, SubsonicFragmentActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - if(!"".equals(fragmentType)) { - intent.putExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE, fragmentType); - } - if(lastSelectedPosition != 0) { - intent.putExtra(Constants.FRAGMENT_POSITION, lastSelectedPosition); - } - startActivity(intent); - finish(); - } + public void startFragmentActivity(String fragmentType) { + Intent intent = new Intent(); + intent.setClass(SubsonicActivity.this, SubsonicFragmentActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + if(!"".equals(fragmentType)) { + intent.putExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE, fragmentType); + } + if(lastSelectedPosition != 0) { + intent.putExtra(Constants.FRAGMENT_POSITION, lastSelectedPosition); + } + startActivity(intent); + finish(); + } - protected void exit() { - if(((Object) this).getClass() != SubsonicFragmentActivity.class) { - Intent intent = new Intent(this, SubsonicFragmentActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - intent.putExtra(Constants.INTENT_EXTRA_NAME_EXIT, true); - Util.startActivityWithoutTransition(this, intent); - } else { - finished = true; - this.stopService(new Intent(this, DownloadService.class)); - this.finish(); - } - } + protected void exit() { + if(((Object) this).getClass() != SubsonicFragmentActivity.class) { + Intent intent = new Intent(this, SubsonicFragmentActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + intent.putExtra(Constants.INTENT_EXTRA_NAME_EXIT, true); + Util.startActivityWithoutTransition(this, intent); + } else { + finished = true; + this.stopService(new Intent(this, DownloadService.class)); + this.finish(); + } + } - public boolean onBackPressedSupport() { - if(drawerOpen) { - drawer.closeDrawers(); - return false; - } else if(backStack.size() > 0) { - removeCurrent(); - return false; - } else { - return true; - } - } + public boolean onBackPressedSupport() { + if(drawerOpen) { + drawer.closeDrawers(); + return false; + } else if(backStack.size() > 0) { + removeCurrent(); + return false; + } else { + return true; + } + } - @Override - public void onBackPressed() { - if(onBackPressedSupport()) { - super.onBackPressed(); - } - } + @Override + public void onBackPressed() { + if(onBackPressedSupport()) { + super.onBackPressed(); + } + } - public SubsonicFragment getCurrentFragment() { - return this.currentFragment; - } + public SubsonicFragment getCurrentFragment() { + return this.currentFragment; + } - public void replaceFragment(SubsonicFragment fragment, int tag) { - replaceFragment(fragment, tag, false); - } - public void replaceFragment(SubsonicFragment fragment, int tag, boolean replaceCurrent) { - SubsonicFragment oldFragment = currentFragment; - if(currentFragment != null) { - currentFragment.setPrimaryFragment(false, secondaryContainer != null); - } - backStack.add(currentFragment); + public void replaceFragment(SubsonicFragment fragment, int tag) { + replaceFragment(fragment, tag, false); + } + public void replaceFragment(SubsonicFragment fragment, int tag, boolean replaceCurrent) { + SubsonicFragment oldFragment = currentFragment; + if(currentFragment != null) { + currentFragment.setPrimaryFragment(false, secondaryContainer != null); + } + backStack.add(currentFragment); - currentFragment = fragment; - currentFragment.setPrimaryFragment(true); - supportInvalidateOptionsMenu(); + currentFragment = fragment; + currentFragment.setPrimaryFragment(true); + supportInvalidateOptionsMenu(); - if(secondaryContainer == null || oldFragment.isAlwaysFullscreen() || currentFragment.isAlwaysStartFullscreen()) { - FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); - trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); - trans.hide(oldFragment); - trans.add(R.id.fragment_container, fragment, tag + ""); - trans.commit(); - } else { - // Make sure secondary container is visible now - secondaryContainer.setVisibility(View.VISIBLE); + if(secondaryContainer == null || oldFragment.isAlwaysFullscreen() || currentFragment.isAlwaysStartFullscreen()) { + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); + trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); + trans.hide(oldFragment); + trans.add(R.id.fragment_container, fragment, tag + ""); + trans.commit(); + } else { + // Make sure secondary container is visible now + secondaryContainer.setVisibility(View.VISIBLE); - FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); - // Check to see if you need to put on top of old left or not - if(backStack.size() > 1) { - // Move old right to left if there is a backstack already - SubsonicFragment newLeftFragment = backStack.get(backStack.size() - 1); - if(replaceCurrent) { - // trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); - } - trans.remove(newLeftFragment); + // Check to see if you need to put on top of old left or not + if(backStack.size() > 1) { + // Move old right to left if there is a backstack already + SubsonicFragment newLeftFragment = backStack.get(backStack.size() - 1); + if(replaceCurrent) { + // trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); + } + trans.remove(newLeftFragment); - // Only move right to left if replaceCurrent is false - if(!replaceCurrent) { - SubsonicFragment oldLeftFragment = backStack.get(backStack.size() - 2); - oldLeftFragment.setSecondaryFragment(false); - // trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); - trans.hide(oldLeftFragment); + // Only move right to left if replaceCurrent is false + if(!replaceCurrent) { + SubsonicFragment oldLeftFragment = backStack.get(backStack.size() - 2); + oldLeftFragment.setSecondaryFragment(false); + // trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); + trans.hide(oldLeftFragment); - // Make sure remove is finished before adding - trans.commit(); - getSupportFragmentManager().executePendingTransactions(); + // Make sure remove is finished before adding + trans.commit(); + getSupportFragmentManager().executePendingTransactions(); - trans = getSupportFragmentManager().beginTransaction(); - // trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); - trans.add(R.id.fragment_container, newLeftFragment, newLeftFragment.getSupportTag() + ""); - } else { - backStack.remove(backStack.size() - 1); - } - } + trans = getSupportFragmentManager().beginTransaction(); + // trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); + trans.add(R.id.fragment_container, newLeftFragment, newLeftFragment.getSupportTag() + ""); + } else { + backStack.remove(backStack.size() - 1); + } + } - // Add fragment to the right container - trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); - trans.add(R.id.fragment_second_container, fragment, tag + ""); + // Add fragment to the right container + trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); + trans.add(R.id.fragment_second_container, fragment, tag + ""); - // Commit it all - trans.commit(); + // Commit it all + trans.commit(); - oldFragment.setIsOnlyVisible(false); - currentFragment.setIsOnlyVisible(false); - } - recreateSpinner(); - } - public void removeCurrent() { - // Don't try to remove current if there is no backstack to remove from - if(backStack.isEmpty()) { - return; - } + oldFragment.setIsOnlyVisible(false); + currentFragment.setIsOnlyVisible(false); + } + recreateSpinner(); + } + public void removeCurrent() { + // Don't try to remove current if there is no backstack to remove from + if(backStack.isEmpty()) { + return; + } - if(currentFragment != null) { - currentFragment.setPrimaryFragment(false); - } - SubsonicFragment oldFragment = currentFragment; + if(currentFragment != null) { + currentFragment.setPrimaryFragment(false); + } + SubsonicFragment oldFragment = currentFragment; - currentFragment = backStack.remove(backStack.size() - 1); - currentFragment.setPrimaryFragment(true, false); - supportInvalidateOptionsMenu(); + currentFragment = backStack.remove(backStack.size() - 1); + currentFragment.setPrimaryFragment(true, false); + supportInvalidateOptionsMenu(); - if(secondaryContainer == null || currentFragment.isAlwaysFullscreen() || oldFragment.isAlwaysStartFullscreen()) { - FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); - trans.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left); - trans.remove(oldFragment); - trans.show(currentFragment); - trans.commit(); - } else { - FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); + if(secondaryContainer == null || currentFragment.isAlwaysFullscreen() || oldFragment.isAlwaysStartFullscreen()) { + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); + trans.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left); + trans.remove(oldFragment); + trans.show(currentFragment); + trans.commit(); + } else { + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); - // Remove old right fragment - trans.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left); - trans.remove(oldFragment); + // Remove old right fragment + trans.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left); + trans.remove(oldFragment); - // Only switch places if there is a backstack, otherwise primary container is correct - if(backStack.size() > 0 && !backStack.get(backStack.size() - 1).isAlwaysFullscreen() && !currentFragment.isAlwaysStartFullscreen()) { - trans.setCustomAnimations(0, 0, 0, 0); - // Add current left fragment to right side - trans.remove(currentFragment); + // Only switch places if there is a backstack, otherwise primary container is correct + if(backStack.size() > 0 && !backStack.get(backStack.size() - 1).isAlwaysFullscreen() && !currentFragment.isAlwaysStartFullscreen()) { + trans.setCustomAnimations(0, 0, 0, 0); + // Add current left fragment to right side + trans.remove(currentFragment); - // Make sure remove is finished before adding - trans.commit(); - getSupportFragmentManager().executePendingTransactions(); + // Make sure remove is finished before adding + trans.commit(); + getSupportFragmentManager().executePendingTransactions(); - trans = getSupportFragmentManager().beginTransaction(); - // trans.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left); - trans.add(R.id.fragment_second_container, currentFragment, currentFragment.getSupportTag() + ""); + trans = getSupportFragmentManager().beginTransaction(); + // trans.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left); + trans.add(R.id.fragment_second_container, currentFragment, currentFragment.getSupportTag() + ""); - SubsonicFragment newLeftFragment = backStack.get(backStack.size() - 1); - newLeftFragment.setSecondaryFragment(true); - trans.show(newLeftFragment); - } else { - secondaryContainer.startAnimation(AnimationUtils.loadAnimation(this, R.anim.exit_to_right)); - secondaryContainer.setVisibility(View.GONE); + SubsonicFragment newLeftFragment = backStack.get(backStack.size() - 1); + newLeftFragment.setSecondaryFragment(true); + trans.show(newLeftFragment); + } else { + secondaryContainer.startAnimation(AnimationUtils.loadAnimation(this, R.anim.exit_to_right)); + secondaryContainer.setVisibility(View.GONE); - currentFragment.setIsOnlyVisible(true); - } + currentFragment.setIsOnlyVisible(true); + } - trans.commit(); - } - recreateSpinner(); - } - public void replaceExistingFragment(SubsonicFragment fragment, int tag) { - FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); - trans.remove(currentFragment); - trans.add(R.id.fragment_container, fragment, tag + ""); - trans.commit(); + trans.commit(); + } + recreateSpinner(); + } + public void replaceExistingFragment(SubsonicFragment fragment, int tag) { + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); + trans.remove(currentFragment); + trans.add(R.id.fragment_container, fragment, tag + ""); + trans.commit(); - currentFragment = fragment; - currentFragment.setPrimaryFragment(true); - supportInvalidateOptionsMenu(); - } + currentFragment = fragment; + currentFragment.setPrimaryFragment(true); + supportInvalidateOptionsMenu(); + } - public void invalidate() { - if(currentFragment != null) { - while(backStack.size() > 0) { - removeCurrent(); - } + public void invalidate() { + if(currentFragment != null) { + while(backStack.size() > 0) { + removeCurrent(); + } currentFragment.invalidate(); - populateTabs(); - } + populateTabs(); + } - supportInvalidateOptionsMenu(); - } + supportInvalidateOptionsMenu(); + } - protected void recreateSpinner() { - if(currentFragment == null || currentFragment.getTitle() == null) { - return; - } - if(spinnerAdapter == null || getSupportActionBar().getCustomView() == null) { - createCustomActionBarView(); - } + protected void recreateSpinner() { + if(currentFragment == null || currentFragment.getTitle() == null) { + return; + } + if(spinnerAdapter == null || getSupportActionBar().getCustomView() == null) { + createCustomActionBarView(); + } - if(backStack.size() > 0) { - createCustomActionBarView(); - spinnerAdapter.clear(); - for(int i = 0; i < backStack.size(); i++) { - CharSequence title = backStack.get(i).getTitle(); - if(title != null) { - spinnerAdapter.add(title); - } else { - spinnerAdapter.add("null"); - } - } - if(currentFragment.getTitle() != null) { - spinnerAdapter.add(currentFragment.getTitle()); - } else { - spinnerAdapter.add("null"); - } - spinnerAdapter.notifyDataSetChanged(); - actionBarSpinner.setSelection(spinnerAdapter.getCount() - 1); + if(backStack.size() > 0) { + createCustomActionBarView(); + spinnerAdapter.clear(); + for(int i = 0; i < backStack.size(); i++) { + CharSequence title = backStack.get(i).getTitle(); + if(title != null) { + spinnerAdapter.add(title); + } else { + spinnerAdapter.add("null"); + } + } + if(currentFragment.getTitle() != null) { + spinnerAdapter.add(currentFragment.getTitle()); + } else { + spinnerAdapter.add("null"); + } + spinnerAdapter.notifyDataSetChanged(); + actionBarSpinner.setSelection(spinnerAdapter.getCount() - 1); getSupportActionBar().setDisplayShowTitleEnabled(false); getSupportActionBar().setDisplayShowCustomEnabled(true); - if(drawerToggle.isDrawerIndicatorEnabled()) { - getSupportActionBar().setDisplayHomeAsUpEnabled(false); - drawerToggle.setDrawerIndicatorEnabled(false); - getSupportActionBar().setDisplayHomeAsUpEnabled(true); - } - } else { - getSupportActionBar().setDisplayShowTitleEnabled(true); - getSupportActionBar().setTitle(currentFragment.getTitle()); - getSupportActionBar().setDisplayShowCustomEnabled(false); - drawerToggle.setDrawerIndicatorEnabled(true); - } - } + if(drawerToggle.isDrawerIndicatorEnabled()) { + getSupportActionBar().setDisplayHomeAsUpEnabled(false); + drawerToggle.setDrawerIndicatorEnabled(false); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + } + } else { + getSupportActionBar().setDisplayShowTitleEnabled(true); + getSupportActionBar().setTitle(currentFragment.getTitle()); + getSupportActionBar().setDisplayShowCustomEnabled(false); + drawerToggle.setDrawerIndicatorEnabled(true); + } + } - protected void restart() { - restart(true); - } - protected void restart(boolean resumePosition) { - Intent intent = new Intent(this, this.getClass()); - intent.putExtras(getIntent()); - if(resumePosition) { - intent.putExtra(Constants.FRAGMENT_POSITION, lastSelectedPosition); - } else { - String fragmentType = Util.openToTab(this); - intent.putExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE, fragmentType); - intent.putExtra(Constants.FRAGMENT_POSITION, getDrawerItemId(fragmentType)); - } - finish(); - Util.startActivityWithoutTransition(this, intent); - } + protected void restart() { + restart(true); + } + protected void restart(boolean resumePosition) { + Intent intent = new Intent(this, this.getClass()); + intent.putExtras(getIntent()); + if(resumePosition) { + intent.putExtra(Constants.FRAGMENT_POSITION, lastSelectedPosition); + } else { + String fragmentType = Util.openToTab(this); + intent.putExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE, fragmentType); + intent.putExtra(Constants.FRAGMENT_POSITION, getDrawerItemId(fragmentType)); + } + finish(); + Util.startActivityWithoutTransition(this, intent); + } - private void applyTheme() { - theme = ThemeUtil.getTheme(this); + private void applyTheme() { + theme = ThemeUtil.getTheme(this); - if(theme != null && theme.indexOf("fullscreen") != -1) { - theme = theme.substring(0, theme.indexOf("_fullscreen")); - ThemeUtil.setTheme(this, theme); - } + if(theme != null && theme.indexOf("fullscreen") != -1) { + theme = theme.substring(0, theme.indexOf("_fullscreen")); + ThemeUtil.setTheme(this, theme); + } - ThemeUtil.applyTheme(this, theme); - actionbarColored = Util.getPreferences(this).getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true); - } - private void applyFullscreen() { - fullScreen = Util.getPreferences(this).getBoolean(Constants.PREFERENCES_KEY_FULL_SCREEN, false); - if(fullScreen ) { + ThemeUtil.applyTheme(this, theme); + actionbarColored = Util.getPreferences(this).getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true); + } + private void applyFullscreen() { + fullScreen = Util.getPreferences(this).getBoolean(Constants.PREFERENCES_KEY_FULL_SCREEN, false); + if(fullScreen ) { int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; getWindow().getDecorView().setSystemUiVisibility(flags); - getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); - } - } + getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); + } + } - public boolean isDestroyedCompat() { - return destroyed; - } + public boolean isDestroyedCompat() { + return destroyed; + } - public synchronized ImageLoader getImageLoader() { - if (IMAGE_LOADER == null) { - IMAGE_LOADER = new ImageLoader(this); - } - return IMAGE_LOADER; - } - public synchronized static ImageLoader getStaticImageLoader(Context context) { - if (IMAGE_LOADER == null) { - IMAGE_LOADER = new ImageLoader(context); - } - return IMAGE_LOADER; - } + public synchronized ImageLoader getImageLoader() { + if (IMAGE_LOADER == null) { + IMAGE_LOADER = new ImageLoader(this); + } + return IMAGE_LOADER; + } + public synchronized static ImageLoader getStaticImageLoader(Context context) { + if (IMAGE_LOADER == null) { + IMAGE_LOADER = new ImageLoader(context); + } + return IMAGE_LOADER; + } - public DownloadService getDownloadService() { - if(finished) { - return null; - } + public DownloadService getDownloadService() { + if(finished) { + return null; + } - // If service is not available, request it to start and wait for it. - for (int i = 0; i < 5; i++) { - DownloadService downloadService = DownloadService.getInstance(); - if (downloadService != null) { - break; - } - Log.w(TAG, "DownloadService not running. Attempting to start it."); - startService(new Intent(this, DownloadService.class)); - Util.sleepQuietly(50L); - } + // If service is not available, request it to start and wait for it. + for (int i = 0; i < 5; i++) { + DownloadService downloadService = DownloadService.getInstance(); + if (downloadService != null) { + break; + } + Log.w(TAG, "DownloadService not running. Attempting to start it."); + startService(new Intent(this, DownloadService.class)); + Util.sleepQuietly(50L); + } - final DownloadService downloadService = DownloadService.getInstance(); - if(downloadService != null && afterServiceAvailable.size() > 0) { - for(Runnable runnable: afterServiceAvailable) { - handler.post(runnable); - } - afterServiceAvailable.clear(); - } - return downloadService; - } - public void runWhenServiceAvailable(Runnable runnable) { - if(getDownloadService() != null) { - runnable.run(); - } else { - afterServiceAvailable.add(runnable); - checkIfServiceAvailable(); - } - } - private void checkIfServiceAvailable() { - if(getDownloadService() == null) { - handler.postDelayed(new Runnable() { - @Override - public void run() { - checkIfServiceAvailable(); - } - }, 50); - } else if(afterServiceAvailable.size() > 0) { - for(Runnable runnable: afterServiceAvailable) { - handler.post(runnable); - } - afterServiceAvailable.clear(); - } - } + final DownloadService downloadService = DownloadService.getInstance(); + if(downloadService != null && afterServiceAvailable.size() > 0) { + for(Runnable runnable: afterServiceAvailable) { + handler.post(runnable); + } + afterServiceAvailable.clear(); + } + return downloadService; + } + public void runWhenServiceAvailable(Runnable runnable) { + if(getDownloadService() != null) { + runnable.run(); + } else { + afterServiceAvailable.add(runnable); + checkIfServiceAvailable(); + } + } + private void checkIfServiceAvailable() { + if(getDownloadService() == null) { + handler.postDelayed(new Runnable() { + @Override + public void run() { + checkIfServiceAvailable(); + } + }, 50); + } else if(afterServiceAvailable.size() > 0) { + for(Runnable runnable: afterServiceAvailable) { + handler.post(runnable); + } + afterServiceAvailable.clear(); + } + } - public static String getThemeName() { - return theme; - } + public static String getThemeName() { + return theme; + } - public boolean isTouchscreen() { - return touchscreen; - } + public boolean isTouchscreen() { + return touchscreen; + } - public void openNowPlaying() { + public void openNowPlaying() { - } - public void closeNowPlaying() { + } + public void closeNowPlaying() { - } + } - public void setActiveServer(int instance) { - if (Util.getActiveServer(this) != instance) { - final DownloadService service = getDownloadService(); - if (service != null) { - new SilentBackgroundTask(this) { - @Override - protected Void doInBackground() throws Throwable { - service.clearIncomplete(); - return null; - } - }.execute(); + public void setActiveServer(int instance) { + if (Util.getActiveServer(this) != instance) { + final DownloadService service = getDownloadService(); + if (service != null) { + new SilentBackgroundTask(this) { + @Override + protected Void doInBackground() throws Throwable { + service.clearIncomplete(); + return null; + } + }.execute(); - } - Util.setActiveServer(this, instance); - invalidate(); - UserUtil.refreshCurrentUser(this, false, true); - updateDrawerHeader(); - } - } - public void updateDrawerHeader() { - if(Util.isOffline(this)) { - drawerServerName.setText(R.string.select_album_offline); - drawerUserName.setText(""); - drawerHeader.setClickable(false); - drawerHeaderToggle.setVisibility(View.GONE); - } else { - drawerServerName.setText(Util.getServerName(this)); - drawerUserName.setText(UserUtil.getCurrentUsername(this)); - drawerHeader.setClickable(true); - drawerHeaderToggle.setVisibility(View.VISIBLE); - } - } + } + Util.setActiveServer(this, instance); + invalidate(); + UserUtil.refreshCurrentUser(this, false, true); + updateDrawerHeader(); + } + } + public void updateDrawerHeader() { + if(Util.isOffline(this)) { + drawerServerName.setText(R.string.select_album_offline); + drawerUserName.setText(""); + drawerHeader.setClickable(false); + drawerHeaderToggle.setVisibility(View.GONE); + } else { + drawerServerName.setText(Util.getServerName(this)); + drawerUserName.setText(UserUtil.getCurrentUsername(this)); + drawerHeader.setClickable(true); + drawerHeaderToggle.setVisibility(View.VISIBLE); + } + } - public void toggleOffline() { - boolean isOffline = Util.isOffline(this); - Util.setOffline(this, !isOffline); - invalidate(); - DownloadService service = getDownloadService(); - if (service != null) { - service.setOnline(isOffline); - } + public void toggleOffline() { + boolean isOffline = Util.isOffline(this); + Util.setOffline(this, !isOffline); + invalidate(); + DownloadService service = getDownloadService(); + if (service != null) { + service.setOnline(isOffline); + } - UserUtil.seedCurrentUser(this); - this.updateDrawerHeader(); - drawer.closeDrawers(); - } + UserUtil.seedCurrentUser(this); + this.updateDrawerHeader(); + drawer.closeDrawers(); + } - public int getDrawerItemId(String fragmentType) { - if(fragmentType == null) { - return R.id.drawer_library; - } + public int getDrawerItemId(String fragmentType) { + if(fragmentType == null) { + return R.id.drawer_library; + } - switch(fragmentType) { - case "Artist": - return R.id.drawer_library; - case "Playlist": - return R.id.drawer_playlists; - default: - return R.id.drawer_library; - } - } + switch(fragmentType) { + case "Artist": + return R.id.drawer_library; + case "Playlist": + return R.id.drawer_playlists; + default: + return R.id.drawer_library; + } + } - private void setUncaughtExceptionHandler() { - Thread.UncaughtExceptionHandler handler = Thread.getDefaultUncaughtExceptionHandler(); - if (!(handler instanceof SubsonicActivity.SubsonicUncaughtExceptionHandler)) { - Thread.setDefaultUncaughtExceptionHandler(new SubsonicActivity.SubsonicUncaughtExceptionHandler(this)); - } - } + private void setUncaughtExceptionHandler() { + Thread.UncaughtExceptionHandler handler = Thread.getDefaultUncaughtExceptionHandler(); + if (!(handler instanceof SubsonicActivity.SubsonicUncaughtExceptionHandler)) { + Thread.setDefaultUncaughtExceptionHandler(new SubsonicActivity.SubsonicUncaughtExceptionHandler(this)); + } + } - /** - * Logs the stack trace of uncaught exceptions to a file on the SD card. - */ - private static class SubsonicUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { + /** + * Logs the stack trace of uncaught exceptions to a file on the SD card. + */ + private static class SubsonicUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { - private final Thread.UncaughtExceptionHandler defaultHandler; - private final Context context; + private final Thread.UncaughtExceptionHandler defaultHandler; + private final Context context; - private SubsonicUncaughtExceptionHandler(Context context) { - this.context = context; - defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); - } + private SubsonicUncaughtExceptionHandler(Context context) { + this.context = context; + defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); + } - @Override - public void uncaughtException(Thread thread, Throwable throwable) { - File file = null; - PrintWriter printWriter = null; - try { + @Override + public void uncaughtException(Thread thread, Throwable throwable) { + File file = null; + PrintWriter printWriter = null; + try { - PackageInfo packageInfo = context.getPackageManager().getPackageInfo("net.nullsum.audinaut", 0); - file = new File(Environment.getExternalStorageDirectory(), "audinaut-stacktrace.txt"); - printWriter = new PrintWriter(file); - printWriter.println("Android API level: " + Build.VERSION.SDK); - printWriter.println("Subsonic version name: " + packageInfo.versionName); - printWriter.println("Subsonic version code: " + packageInfo.versionCode); - printWriter.println(); - throwable.printStackTrace(printWriter); - Log.i(TAG, "Stack trace written to " + file); - } catch (Throwable x) { - Log.e(TAG, "Failed to write stack trace to " + file, x); - } finally { - Util.close(printWriter); - if (defaultHandler != null) { - defaultHandler.uncaughtException(thread, throwable); - } + PackageInfo packageInfo = context.getPackageManager().getPackageInfo("net.nullsum.audinaut", 0); + file = new File(Environment.getExternalStorageDirectory(), "audinaut-stacktrace.txt"); + printWriter = new PrintWriter(file); + printWriter.println("Android API level: " + Build.VERSION.SDK); + printWriter.println("Subsonic version name: " + packageInfo.versionName); + printWriter.println("Subsonic version code: " + packageInfo.versionCode); + printWriter.println(); + throwable.printStackTrace(printWriter); + Log.i(TAG, "Stack trace written to " + file); + } catch (Throwable x) { + Log.e(TAG, "Failed to write stack trace to " + file, x); + } finally { + Util.close(printWriter); + if (defaultHandler != null) { + defaultHandler.uncaughtException(thread, throwable); + } - } - } - } + } + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/activity/SubsonicFragmentActivity.java b/app/src/main/java/net/nullsum/audinaut/activity/SubsonicFragmentActivity.java index 05d9623..c1839dc 100644 --- a/app/src/main/java/net/nullsum/audinaut/activity/SubsonicFragmentActivity.java +++ b/app/src/main/java/net/nullsum/audinaut/activity/SubsonicFragmentActivity.java @@ -79,120 +79,120 @@ import net.nullsum.audinaut.util.Util; * Created by Scott on 10/14/13. */ public class SubsonicFragmentActivity extends SubsonicActivity implements DownloadService.OnSongChangedListener { - private static String TAG = SubsonicFragmentActivity.class.getSimpleName(); - private static boolean infoDialogDisplayed; - private static boolean sessionInitialized = false; - private static long ALLOWED_SKEW = 30000L; + private static String TAG = SubsonicFragmentActivity.class.getSimpleName(); + private static boolean infoDialogDisplayed; + private static boolean sessionInitialized = false; + private static long ALLOWED_SKEW = 30000L; - private SlidingUpPanelLayout slideUpPanel; - private SlidingUpPanelLayout.PanelSlideListener panelSlideListener; - private boolean isPanelClosing = false; - private NowPlayingFragment nowPlayingFragment; - private SubsonicFragment secondaryFragment; - private Toolbar mainToolbar; - private Toolbar nowPlayingToolbar; + private SlidingUpPanelLayout slideUpPanel; + private SlidingUpPanelLayout.PanelSlideListener panelSlideListener; + private boolean isPanelClosing = false; + private NowPlayingFragment nowPlayingFragment; + private SubsonicFragment secondaryFragment; + private Toolbar mainToolbar; + private Toolbar nowPlayingToolbar; - private View bottomBar; - private ImageView coverArtView; - private TextView trackView; - private TextView artistView; - private ImageButton startButton; - private long lastBackPressTime = 0; - private DownloadFile currentPlaying; - private PlayerState currentState; - private ImageButton previousButton; - private ImageButton nextButton; - private ImageButton rewindButton; - private ImageButton fastforwardButton; + private View bottomBar; + private ImageView coverArtView; + private TextView trackView; + private TextView artistView; + private ImageButton startButton; + private long lastBackPressTime = 0; + private DownloadFile currentPlaying; + private PlayerState currentState; + private ImageButton previousButton; + private ImageButton nextButton; + private ImageButton rewindButton; + private ImageButton fastforwardButton; - @Override - public void onCreate(Bundle savedInstanceState) { - if(savedInstanceState == null) { - String fragmentType = getIntent().getStringExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE); - boolean firstRun = false; - if (fragmentType == null) { - fragmentType = Util.openToTab(this); - if (fragmentType != null) { - firstRun = true; - } - } + @Override + public void onCreate(Bundle savedInstanceState) { + if(savedInstanceState == null) { + String fragmentType = getIntent().getStringExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE); + boolean firstRun = false; + if (fragmentType == null) { + fragmentType = Util.openToTab(this); + if (fragmentType != null) { + firstRun = true; + } + } - if ("".equals(fragmentType) || fragmentType == null || firstRun) { - // Initial startup stuff - if (!sessionInitialized) { - loadSession(); - } - } - } + if ("".equals(fragmentType) || fragmentType == null || firstRun) { + // Initial startup stuff + if (!sessionInitialized) { + loadSession(); + } + } + } - super.onCreate(savedInstanceState); - if (getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_EXIT)) { - stopService(new Intent(this, DownloadService.class)); - finish(); - getImageLoader().clearCache(); - } else if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD_VIEW)) { - getIntent().putExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE, "Download"); - lastSelectedPosition = R.id.drawer_downloading; - } - setContentView(R.layout.abstract_fragment_activity); + super.onCreate(savedInstanceState); + if (getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_EXIT)) { + stopService(new Intent(this, DownloadService.class)); + finish(); + getImageLoader().clearCache(); + } else if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD_VIEW)) { + getIntent().putExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE, "Download"); + lastSelectedPosition = R.id.drawer_downloading; + } + setContentView(R.layout.abstract_fragment_activity); - if (findViewById(R.id.fragment_container) != null && savedInstanceState == null) { - String fragmentType = getIntent().getStringExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE); - if(fragmentType == null) { - fragmentType = Util.openToTab(this); - if(fragmentType != null) { - getIntent().putExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE, fragmentType); - lastSelectedPosition = getDrawerItemId(fragmentType); - } else { - lastSelectedPosition = R.id.drawer_library; - } + if (findViewById(R.id.fragment_container) != null && savedInstanceState == null) { + String fragmentType = getIntent().getStringExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE); + if(fragmentType == null) { + fragmentType = Util.openToTab(this); + if(fragmentType != null) { + getIntent().putExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE, fragmentType); + lastSelectedPosition = getDrawerItemId(fragmentType); + } else { + lastSelectedPosition = R.id.drawer_library; + } - MenuItem item = drawerList.getMenu().findItem(lastSelectedPosition); - if(item != null) { - item.setChecked(true); - } - } else { - lastSelectedPosition = getDrawerItemId(fragmentType); - } + MenuItem item = drawerList.getMenu().findItem(lastSelectedPosition); + if(item != null) { + item.setChecked(true); + } + } else { + lastSelectedPosition = getDrawerItemId(fragmentType); + } - currentFragment = getNewFragment(fragmentType); - if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_ID)) { - Bundle currentArguments = currentFragment.getArguments(); - if(currentArguments == null) { - currentArguments = new Bundle(); - } - currentArguments.putString(Constants.INTENT_EXTRA_NAME_ID, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_ID)); - currentFragment.setArguments(currentArguments); - } - currentFragment.setPrimaryFragment(true); - getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, currentFragment, currentFragment.getSupportTag() + "").commit(); + currentFragment = getNewFragment(fragmentType); + if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_ID)) { + Bundle currentArguments = currentFragment.getArguments(); + if(currentArguments == null) { + currentArguments = new Bundle(); + } + currentArguments.putString(Constants.INTENT_EXTRA_NAME_ID, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_ID)); + currentFragment.setArguments(currentArguments); + } + currentFragment.setPrimaryFragment(true); + getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, currentFragment, currentFragment.getSupportTag() + "").commit(); - if(getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY) != null) { - SearchFragment fragment = new SearchFragment(); - replaceFragment(fragment, fragment.getSupportTag()); - } + if(getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY) != null) { + SearchFragment fragment = new SearchFragment(); + replaceFragment(fragment, fragment.getSupportTag()); + } - // If a album type is set, switch to that album type view - String albumType = getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE); - if(albumType != null) { - SubsonicFragment fragment = new SelectDirectoryFragment(); + // If a album type is set, switch to that album type view + String albumType = getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE); + if(albumType != null) { + SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, albumType); - args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20); - args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, albumType); + args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20); + args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0); - fragment.setArguments(args); - replaceFragment(fragment, fragment.getSupportTag()); - } - } + fragment.setArguments(args); + replaceFragment(fragment, fragment.getSupportTag()); + } + } - slideUpPanel = (SlidingUpPanelLayout) findViewById(R.id.slide_up_panel); - panelSlideListener = new SlidingUpPanelLayout.PanelSlideListener() { - @Override - public void onPanelSlide(View panel, float slideOffset) { + slideUpPanel = (SlidingUpPanelLayout) findViewById(R.id.slide_up_panel); + panelSlideListener = new SlidingUpPanelLayout.PanelSlideListener() { + @Override + public void onPanelSlide(View panel, float slideOffset) { - } + } @Override public void onPanelStateChanged(View panel, PanelState previousState, PanelState newState) { @@ -227,633 +227,633 @@ public class SubsonicFragmentActivity extends SubsonicActivity implements Downlo getSupportActionBar().setDisplayHomeAsUpEnabled(true); } } - }; - slideUpPanel.addPanelSlideListener(panelSlideListener); + }; + slideUpPanel.addPanelSlideListener(panelSlideListener); - if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD)) { - // Post this later so it actually runs - handler.postDelayed(new Runnable() { - @Override - public void run() { - openNowPlaying(); - } - }, 200); + if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD)) { + // Post this later so it actually runs + handler.postDelayed(new Runnable() { + @Override + public void run() { + openNowPlaying(); + } + }, 200); - getIntent().removeExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD); - } + getIntent().removeExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD); + } - bottomBar = findViewById(R.id.bottom_bar); - mainToolbar = (Toolbar) findViewById(R.id.main_toolbar); - nowPlayingToolbar = (Toolbar) findViewById(R.id.now_playing_toolbar); - coverArtView = (ImageView) bottomBar.findViewById(R.id.album_art); - trackView = (TextView) bottomBar.findViewById(R.id.track_name); - artistView = (TextView) bottomBar.findViewById(R.id.artist_name); + bottomBar = findViewById(R.id.bottom_bar); + mainToolbar = (Toolbar) findViewById(R.id.main_toolbar); + nowPlayingToolbar = (Toolbar) findViewById(R.id.now_playing_toolbar); + coverArtView = (ImageView) bottomBar.findViewById(R.id.album_art); + trackView = (TextView) bottomBar.findViewById(R.id.track_name); + artistView = (TextView) bottomBar.findViewById(R.id.artist_name); - setSupportActionBar(mainToolbar); + setSupportActionBar(mainToolbar); - if (findViewById(R.id.fragment_container) != null && savedInstanceState == null) { - nowPlayingFragment = new NowPlayingFragment(); - FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); - trans.add(R.id.now_playing_fragment_container, nowPlayingFragment, nowPlayingFragment.getTag() + ""); - trans.commit(); - } + if (findViewById(R.id.fragment_container) != null && savedInstanceState == null) { + nowPlayingFragment = new NowPlayingFragment(); + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); + trans.add(R.id.now_playing_fragment_container, nowPlayingFragment, nowPlayingFragment.getTag() + ""); + trans.commit(); + } - rewindButton = (ImageButton) findViewById(R.id.download_rewind); - rewindButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - new SilentBackgroundTask(SubsonicFragmentActivity.this) { - @Override - protected Void doInBackground() throws Throwable { - if (getDownloadService() == null) { - return null; - } + rewindButton = (ImageButton) findViewById(R.id.download_rewind); + rewindButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new SilentBackgroundTask(SubsonicFragmentActivity.this) { + @Override + protected Void doInBackground() throws Throwable { + if (getDownloadService() == null) { + return null; + } - getDownloadService().rewind(); - return null; - } - }.execute(); - } - }); + getDownloadService().rewind(); + return null; + } + }.execute(); + } + }); - previousButton = (ImageButton) findViewById(R.id.download_previous); - previousButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - new SilentBackgroundTask(SubsonicFragmentActivity.this) { - @Override - protected Void doInBackground() throws Throwable { - if(getDownloadService() == null) { - return null; - } + previousButton = (ImageButton) findViewById(R.id.download_previous); + previousButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new SilentBackgroundTask(SubsonicFragmentActivity.this) { + @Override + protected Void doInBackground() throws Throwable { + if(getDownloadService() == null) { + return null; + } - getDownloadService().previous(); - return null; - } - }.execute(); - } - }); + getDownloadService().previous(); + return null; + } + }.execute(); + } + }); - startButton = (ImageButton) findViewById(R.id.download_start); - startButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - new SilentBackgroundTask(SubsonicFragmentActivity.this) { - @Override - protected Void doInBackground() throws Throwable { - PlayerState state = getDownloadService().getPlayerState(); - if(state == PlayerState.STARTED) { - getDownloadService().pause(); - } else { - getDownloadService().start(); - } + startButton = (ImageButton) findViewById(R.id.download_start); + startButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new SilentBackgroundTask(SubsonicFragmentActivity.this) { + @Override + protected Void doInBackground() throws Throwable { + PlayerState state = getDownloadService().getPlayerState(); + if(state == PlayerState.STARTED) { + getDownloadService().pause(); + } else { + getDownloadService().start(); + } - return null; - } - }.execute(); - } - }); + return null; + } + }.execute(); + } + }); - nextButton = (ImageButton) findViewById(R.id.download_next); - nextButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - new SilentBackgroundTask(SubsonicFragmentActivity.this) { - @Override - protected Void doInBackground() throws Throwable { - if(getDownloadService() == null) { - return null; - } + nextButton = (ImageButton) findViewById(R.id.download_next); + nextButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new SilentBackgroundTask(SubsonicFragmentActivity.this) { + @Override + protected Void doInBackground() throws Throwable { + if(getDownloadService() == null) { + return null; + } - getDownloadService().next(); - return null; - } - }.execute(); - } - }); + getDownloadService().next(); + return null; + } + }.execute(); + } + }); - fastforwardButton = (ImageButton) findViewById(R.id.download_fastforward); - fastforwardButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - new SilentBackgroundTask(SubsonicFragmentActivity.this) { - @Override - protected Void doInBackground() throws Throwable { - if (getDownloadService() == null) { - return null; - } + fastforwardButton = (ImageButton) findViewById(R.id.download_fastforward); + fastforwardButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new SilentBackgroundTask(SubsonicFragmentActivity.this) { + @Override + protected Void doInBackground() throws Throwable { + if (getDownloadService() == null) { + return null; + } - getDownloadService().fastForward(); - return null; - } - }.execute(); - } - }); - } + getDownloadService().fastForward(); + return null; + } + }.execute(); + } + }); + } - @Override - protected void onPostCreate(Bundle bundle) { - super.onPostCreate(bundle); + @Override + protected void onPostCreate(Bundle bundle) { + super.onPostCreate(bundle); - showInfoDialog(); - checkUpdates(); - } + showInfoDialog(); + checkUpdates(); + } - @Override - public void onNewIntent(Intent intent) { - super.onNewIntent(intent); + @Override + public void onNewIntent(Intent intent) { + super.onNewIntent(intent); - if(currentFragment != null && intent.getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY) != null) { - if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { - closeNowPlaying(); - } + if(currentFragment != null && intent.getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY) != null) { + if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { + closeNowPlaying(); + } - if(currentFragment instanceof SearchFragment) { - String query = intent.getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY); - boolean autoplay = intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false); + if(currentFragment instanceof SearchFragment) { + String query = intent.getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY); + boolean autoplay = intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false); - if (query != null) { - ((SearchFragment)currentFragment).search(query, autoplay); - } - getIntent().removeExtra(Constants.INTENT_EXTRA_NAME_QUERY); - } else { - setIntent(intent); + if (query != null) { + ((SearchFragment)currentFragment).search(query, autoplay); + } + getIntent().removeExtra(Constants.INTENT_EXTRA_NAME_QUERY); + } else { + setIntent(intent); - SearchFragment fragment = new SearchFragment(); - replaceFragment(fragment, fragment.getSupportTag()); - } - } else if(intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD, false)) { - if(slideUpPanel.getPanelState() != SlidingUpPanelLayout.PanelState.EXPANDED) { - openNowPlaying(); - } - } else { - if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { - closeNowPlaying(); - } - setIntent(intent); - } - if(drawer != null) { - drawer.closeDrawers(); - } - } + SearchFragment fragment = new SearchFragment(); + replaceFragment(fragment, fragment.getSupportTag()); + } + } else if(intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD, false)) { + if(slideUpPanel.getPanelState() != SlidingUpPanelLayout.PanelState.EXPANDED) { + openNowPlaying(); + } + } else { + if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { + closeNowPlaying(); + } + setIntent(intent); + } + if(drawer != null) { + drawer.closeDrawers(); + } + } - @Override - public void onResume() { - super.onResume(); + @Override + public void onResume() { + super.onResume(); - if(getIntent().hasExtra(Constants.INTENT_EXTRA_VIEW_ALBUM)) { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_ID, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_ID)); - args.putString(Constants.INTENT_EXTRA_NAME_NAME, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_NAME)); - args.putString(Constants.INTENT_EXTRA_SEARCH_SONG, getIntent().getStringExtra(Constants.INTENT_EXTRA_SEARCH_SONG)); - if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_ARTIST)) { - args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); - } - if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_CHILD_ID)) { - args.putString(Constants.INTENT_EXTRA_NAME_CHILD_ID, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_CHILD_ID)); - } - fragment.setArguments(args); + if(getIntent().hasExtra(Constants.INTENT_EXTRA_VIEW_ALBUM)) { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_ID, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_ID)); + args.putString(Constants.INTENT_EXTRA_NAME_NAME, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_NAME)); + args.putString(Constants.INTENT_EXTRA_SEARCH_SONG, getIntent().getStringExtra(Constants.INTENT_EXTRA_SEARCH_SONG)); + if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_ARTIST)) { + args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); + } + if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_CHILD_ID)) { + args.putString(Constants.INTENT_EXTRA_NAME_CHILD_ID, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_CHILD_ID)); + } + fragment.setArguments(args); - replaceFragment(fragment, fragment.getSupportTag()); - getIntent().removeExtra(Constants.INTENT_EXTRA_VIEW_ALBUM); - } + replaceFragment(fragment, fragment.getSupportTag()); + getIntent().removeExtra(Constants.INTENT_EXTRA_VIEW_ALBUM); + } - UserUtil.seedCurrentUser(this); - createAccount(); - runWhenServiceAvailable(new Runnable() { - @Override - public void run() { - getDownloadService().addOnSongChangedListener(SubsonicFragmentActivity.this, true); - } - }); - } + UserUtil.seedCurrentUser(this); + createAccount(); + runWhenServiceAvailable(new Runnable() { + @Override + public void run() { + getDownloadService().addOnSongChangedListener(SubsonicFragmentActivity.this, true); + } + }); + } - @Override - public void onPause() { - super.onPause(); - DownloadService downloadService = getDownloadService(); - if(downloadService != null) { - downloadService.removeOnSongChangeListener(this); - } - } + @Override + public void onPause() { + super.onPause(); + DownloadService downloadService = getDownloadService(); + if(downloadService != null) { + downloadService.removeOnSongChangeListener(this); + } + } - @Override - public void onSaveInstanceState(Bundle savedInstanceState) { - super.onSaveInstanceState(savedInstanceState); - savedInstanceState.putString(Constants.MAIN_NOW_PLAYING, nowPlayingFragment.getTag()); - if(secondaryFragment != null) { - savedInstanceState.putString(Constants.MAIN_NOW_PLAYING_SECONDARY, secondaryFragment.getTag()); - } - savedInstanceState.putInt(Constants.MAIN_SLIDE_PANEL_STATE, slideUpPanel.getPanelState().hashCode()); - } - @Override - public void onRestoreInstanceState(Bundle savedInstanceState) { - super.onRestoreInstanceState(savedInstanceState); + @Override + public void onSaveInstanceState(Bundle savedInstanceState) { + super.onSaveInstanceState(savedInstanceState); + savedInstanceState.putString(Constants.MAIN_NOW_PLAYING, nowPlayingFragment.getTag()); + if(secondaryFragment != null) { + savedInstanceState.putString(Constants.MAIN_NOW_PLAYING_SECONDARY, secondaryFragment.getTag()); + } + savedInstanceState.putInt(Constants.MAIN_SLIDE_PANEL_STATE, slideUpPanel.getPanelState().hashCode()); + } + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) { + super.onRestoreInstanceState(savedInstanceState); - String id = savedInstanceState.getString(Constants.MAIN_NOW_PLAYING); - FragmentManager fm = getSupportFragmentManager(); - nowPlayingFragment = (NowPlayingFragment) fm.findFragmentByTag(id); + String id = savedInstanceState.getString(Constants.MAIN_NOW_PLAYING); + FragmentManager fm = getSupportFragmentManager(); + nowPlayingFragment = (NowPlayingFragment) fm.findFragmentByTag(id); - String secondaryId = savedInstanceState.getString(Constants.MAIN_NOW_PLAYING_SECONDARY); - if(secondaryId != null) { - secondaryFragment = (SubsonicFragment) fm.findFragmentByTag(secondaryId); + String secondaryId = savedInstanceState.getString(Constants.MAIN_NOW_PLAYING_SECONDARY); + if(secondaryId != null) { + secondaryFragment = (SubsonicFragment) fm.findFragmentByTag(secondaryId); - nowPlayingFragment.setPrimaryFragment(false); - secondaryFragment.setPrimaryFragment(true); + nowPlayingFragment.setPrimaryFragment(false); + secondaryFragment.setPrimaryFragment(true); - FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); - trans.hide(nowPlayingFragment); - trans.commit(); - } + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); + trans.hide(nowPlayingFragment); + trans.commit(); + } - if(drawerToggle != null && backStack.size() > 0) { - drawerToggle.setDrawerIndicatorEnabled(false); - } + if(drawerToggle != null && backStack.size() > 0) { + drawerToggle.setDrawerIndicatorEnabled(false); + } - if(savedInstanceState.getInt(Constants.MAIN_SLIDE_PANEL_STATE, -1) == SlidingUpPanelLayout.PanelState.EXPANDED.hashCode()) { - panelSlideListener.onPanelStateChanged(null, null, PanelState.EXPANDED); - } - } + if(savedInstanceState.getInt(Constants.MAIN_SLIDE_PANEL_STATE, -1) == SlidingUpPanelLayout.PanelState.EXPANDED.hashCode()) { + panelSlideListener.onPanelStateChanged(null, null, PanelState.EXPANDED); + } + } - @Override - public void setContentView(int viewId) { - super.setContentView(viewId); - if(drawerToggle != null){ - drawerToggle.setDrawerIndicatorEnabled(true); - } - } + @Override + public void setContentView(int viewId) { + super.setContentView(viewId); + if(drawerToggle != null){ + drawerToggle.setDrawerIndicatorEnabled(true); + } + } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return super.onOptionsItemSelected(item); - } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + return super.onOptionsItemSelected(item); + } - @Override - public void onBackPressed() { - if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED && secondaryFragment == null) { - slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED); - } else if(onBackPressedSupport()) { + @Override + public void onBackPressed() { + if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED && secondaryFragment == null) { + slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED); + } else if(onBackPressedSupport()) { finish(); - } - } + } + } - @Override - public boolean onBackPressedSupport() { - if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { - removeCurrent(); - return false; - } else { - return super.onBackPressedSupport(); - } - } + @Override + public boolean onBackPressedSupport() { + if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { + removeCurrent(); + return false; + } else { + return super.onBackPressedSupport(); + } + } - @Override - public SubsonicFragment getCurrentFragment() { - if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { - if(secondaryFragment == null) { - return nowPlayingFragment; - } else { - return secondaryFragment; - } - } else { - return super.getCurrentFragment(); - } - } + @Override + public SubsonicFragment getCurrentFragment() { + if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { + if(secondaryFragment == null) { + return nowPlayingFragment; + } else { + return secondaryFragment; + } + } else { + return super.getCurrentFragment(); + } + } - @Override - public void replaceFragment(SubsonicFragment fragment, int tag, boolean replaceCurrent) { - if(slideUpPanel != null && slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED && !isPanelClosing) { - secondaryFragment = fragment; - nowPlayingFragment.setPrimaryFragment(false); - secondaryFragment.setPrimaryFragment(true); - supportInvalidateOptionsMenu(); + @Override + public void replaceFragment(SubsonicFragment fragment, int tag, boolean replaceCurrent) { + if(slideUpPanel != null && slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED && !isPanelClosing) { + secondaryFragment = fragment; + nowPlayingFragment.setPrimaryFragment(false); + secondaryFragment.setPrimaryFragment(true); + supportInvalidateOptionsMenu(); - FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); - trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); - trans.hide(nowPlayingFragment); - trans.add(R.id.now_playing_fragment_container, secondaryFragment, tag + ""); - trans.commit(); - } else { - super.replaceFragment(fragment, tag, replaceCurrent); - } - } - @Override - public void removeCurrent() { - if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED && secondaryFragment != null) { - FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); - trans.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left); - trans.remove(secondaryFragment); - trans.show(nowPlayingFragment); - trans.commit(); + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); + trans.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); + trans.hide(nowPlayingFragment); + trans.add(R.id.now_playing_fragment_container, secondaryFragment, tag + ""); + trans.commit(); + } else { + super.replaceFragment(fragment, tag, replaceCurrent); + } + } + @Override + public void removeCurrent() { + if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED && secondaryFragment != null) { + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); + trans.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left); + trans.remove(secondaryFragment); + trans.show(nowPlayingFragment); + trans.commit(); - secondaryFragment = null; - nowPlayingFragment.setPrimaryFragment(true); - supportInvalidateOptionsMenu(); - } else { - super.removeCurrent(); - } - } + secondaryFragment = null; + nowPlayingFragment.setPrimaryFragment(true); + supportInvalidateOptionsMenu(); + } else { + super.removeCurrent(); + } + } - @Override - public void setTitle(CharSequence title) { - if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { - getSupportActionBar().setTitle(title); - } else { - super.setTitle(title); - } - } + @Override + public void setTitle(CharSequence title) { + if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { + getSupportActionBar().setTitle(title); + } else { + super.setTitle(title); + } + } - @Override - protected void drawerItemSelected(String fragmentType) { - super.drawerItemSelected(fragmentType); + @Override + protected void drawerItemSelected(String fragmentType) { + super.drawerItemSelected(fragmentType); - if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { - slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED); - } - } + if(slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED) { + slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED); + } + } - @Override - public void startFragmentActivity(String fragmentType) { - // Create a transaction that does all of this - FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); + @Override + public void startFragmentActivity(String fragmentType) { + // Create a transaction that does all of this + FragmentTransaction trans = getSupportFragmentManager().beginTransaction(); - // Clear existing stack - for(int i = backStack.size() - 1; i >= 0; i--) { - trans.remove(backStack.get(i)); - } - trans.remove(currentFragment); - backStack.clear(); + // Clear existing stack + for(int i = backStack.size() - 1; i >= 0; i--) { + trans.remove(backStack.get(i)); + } + trans.remove(currentFragment); + backStack.clear(); - // Create new stack - currentFragment = getNewFragment(fragmentType); - currentFragment.setPrimaryFragment(true); - trans.add(R.id.fragment_container, currentFragment, currentFragment.getSupportTag() + ""); + // Create new stack + currentFragment = getNewFragment(fragmentType); + currentFragment.setPrimaryFragment(true); + trans.add(R.id.fragment_container, currentFragment, currentFragment.getSupportTag() + ""); - // Done, cleanup - trans.commit(); - supportInvalidateOptionsMenu(); - recreateSpinner(); - if(drawer != null) { - drawer.closeDrawers(); - } + // Done, cleanup + trans.commit(); + supportInvalidateOptionsMenu(); + recreateSpinner(); + if(drawer != null) { + drawer.closeDrawers(); + } - if(secondaryContainer != null) { - secondaryContainer.setVisibility(View.GONE); - } - if(drawerToggle != null) { - drawerToggle.setDrawerIndicatorEnabled(true); - } - } + if(secondaryContainer != null) { + secondaryContainer.setVisibility(View.GONE); + } + if(drawerToggle != null) { + drawerToggle.setDrawerIndicatorEnabled(true); + } + } - @Override - public void openNowPlaying() { - slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED); - } - @Override - public void closeNowPlaying() { - slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED); - isPanelClosing = true; - } + @Override + public void openNowPlaying() { + slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.EXPANDED); + } + @Override + public void closeNowPlaying() { + slideUpPanel.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED); + isPanelClosing = true; + } - private SubsonicFragment getNewFragment(String fragmentType) { - if("Artist".equals(fragmentType)) { - return new SelectArtistFragment(); - } else if("Playlist".equals(fragmentType)) { - return new SelectPlaylistFragment(); - } else if("Download".equals(fragmentType)) { - return new DownloadFragment(); - } else { - return new SelectArtistFragment(); - } - } + private SubsonicFragment getNewFragment(String fragmentType) { + if("Artist".equals(fragmentType)) { + return new SelectArtistFragment(); + } else if("Playlist".equals(fragmentType)) { + return new SelectPlaylistFragment(); + } else if("Download".equals(fragmentType)) { + return new DownloadFragment(); + } else { + return new SelectArtistFragment(); + } + } - public void checkUpdates() { - try { - String version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; - int ver = Integer.parseInt(version.replace(".", "")); - Updater updater = new Updater(ver); - updater.checkUpdates(this); - } - catch(Exception e) { + public void checkUpdates() { + try { + String version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName; + int ver = Integer.parseInt(version.replace(".", "")); + Updater updater = new Updater(ver); + updater.checkUpdates(this); + } + catch(Exception e) { - } - } + } + } - private void loadSession() { - loadSettings(); - // If we are on Subsonic 5.2+, save play queue - if(!Util.isOffline(this)) { - loadRemotePlayQueue(); - } + private void loadSession() { + loadSettings(); + // If we are on Subsonic 5.2+, save play queue + if(!Util.isOffline(this)) { + loadRemotePlayQueue(); + } - sessionInitialized = true; - } - private void loadSettings() { - PreferenceManager.setDefaultValues(this, R.xml.settings_appearance, false); - PreferenceManager.setDefaultValues(this, R.xml.settings_cache, false); - PreferenceManager.setDefaultValues(this, R.xml.settings_playback, false); + sessionInitialized = true; + } + private void loadSettings() { + PreferenceManager.setDefaultValues(this, R.xml.settings_appearance, false); + PreferenceManager.setDefaultValues(this, R.xml.settings_cache, false); + PreferenceManager.setDefaultValues(this, R.xml.settings_playback, false); - SharedPreferences prefs = Util.getPreferences(this); - if (!prefs.contains(Constants.PREFERENCES_KEY_CACHE_LOCATION) || prefs.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null) == null) { - resetCacheLocation(prefs); - } else { - String path = prefs.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null); - File cacheLocation = new File(path); - if(!FileUtil.verifyCanWrite(cacheLocation)) { - // Only warn user if there is a difference saved - if(resetCacheLocation(prefs)) { - Util.info(this, R.string.common_warning, R.string.settings_cache_location_reset); - } - } - } + SharedPreferences prefs = Util.getPreferences(this); + if (!prefs.contains(Constants.PREFERENCES_KEY_CACHE_LOCATION) || prefs.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null) == null) { + resetCacheLocation(prefs); + } else { + String path = prefs.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null); + File cacheLocation = new File(path); + if(!FileUtil.verifyCanWrite(cacheLocation)) { + // Only warn user if there is a difference saved + if(resetCacheLocation(prefs)) { + Util.info(this, R.string.common_warning, R.string.settings_cache_location_reset); + } + } + } - if (!prefs.contains(Constants.PREFERENCES_KEY_OFFLINE)) { - SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(Constants.PREFERENCES_KEY_OFFLINE, false); + if (!prefs.contains(Constants.PREFERENCES_KEY_OFFLINE)) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean(Constants.PREFERENCES_KEY_OFFLINE, false); - editor.putString(Constants.PREFERENCES_KEY_SERVER_NAME + 1, "Demo Server"); - editor.putString(Constants.PREFERENCES_KEY_SERVER_URL + 1, "http://demo.subsonic.org"); - editor.putString(Constants.PREFERENCES_KEY_USERNAME + 1, "guest5"); - editor.putString(Constants.PREFERENCES_KEY_PASSWORD + 1, "guest"); - editor.putInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1); - editor.apply(); - } - if(!prefs.contains(Constants.PREFERENCES_KEY_SERVER_COUNT)) { - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt(Constants.PREFERENCES_KEY_SERVER_COUNT, 1); - editor.apply(); - } - } + editor.putString(Constants.PREFERENCES_KEY_SERVER_NAME + 1, "Demo Server"); + editor.putString(Constants.PREFERENCES_KEY_SERVER_URL + 1, "http://demo.subsonic.org"); + editor.putString(Constants.PREFERENCES_KEY_USERNAME + 1, "guest5"); + editor.putString(Constants.PREFERENCES_KEY_PASSWORD + 1, "guest"); + editor.putInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1); + editor.apply(); + } + if(!prefs.contains(Constants.PREFERENCES_KEY_SERVER_COUNT)) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putInt(Constants.PREFERENCES_KEY_SERVER_COUNT, 1); + editor.apply(); + } + } - private boolean resetCacheLocation(SharedPreferences prefs) { - String newDirectory = FileUtil.getDefaultMusicDirectory(this).getPath(); - String oldDirectory = prefs.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null); - if(newDirectory == null || (oldDirectory != null && newDirectory.equals(oldDirectory))) { - return false; - } else { - SharedPreferences.Editor editor = prefs.edit(); - editor.putString(Constants.PREFERENCES_KEY_CACHE_LOCATION, newDirectory); - editor.apply(); - return true; - } - } + private boolean resetCacheLocation(SharedPreferences prefs) { + String newDirectory = FileUtil.getDefaultMusicDirectory(this).getPath(); + String oldDirectory = prefs.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null); + if(newDirectory == null || (oldDirectory != null && newDirectory.equals(oldDirectory))) { + return false; + } else { + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(Constants.PREFERENCES_KEY_CACHE_LOCATION, newDirectory); + editor.apply(); + return true; + } + } - private void loadRemotePlayQueue() { - if(Util.getPreferences(this).getBoolean(Constants.PREFERENCES_KEY_RESUME_PLAY_QUEUE_NEVER, false)) { - return; - } + private void loadRemotePlayQueue() { + if(Util.getPreferences(this).getBoolean(Constants.PREFERENCES_KEY_RESUME_PLAY_QUEUE_NEVER, false)) { + return; + } - final SubsonicActivity context = this; - new SilentBackgroundTask(this) { - private PlayerQueue playerQueue; + final SubsonicActivity context = this; + new SilentBackgroundTask(this) { + private PlayerQueue playerQueue; - @Override - protected Void doInBackground() throws Throwable { - try { - MusicService musicService = MusicServiceFactory.getMusicService(context); - PlayerQueue remoteState = musicService.getPlayQueue(context, null); + @Override + protected Void doInBackground() throws Throwable { + try { + MusicService musicService = MusicServiceFactory.getMusicService(context); + PlayerQueue remoteState = musicService.getPlayQueue(context, null); - // Make sure we wait until download service is ready - DownloadService downloadService = getDownloadService(); - while(downloadService == null || !downloadService.isInitialized()) { - Util.sleepQuietly(100L); - downloadService = getDownloadService(); - } + // Make sure we wait until download service is ready + DownloadService downloadService = getDownloadService(); + while(downloadService == null || !downloadService.isInitialized()) { + Util.sleepQuietly(100L); + downloadService = getDownloadService(); + } - // If we had a remote state and it's changed is more recent than our existing state - if(remoteState != null && remoteState.changed != null) { - // Check if changed + 30 seconds since some servers have slight skew - Date remoteChange = new Date(remoteState.changed.getTime() - ALLOWED_SKEW); - Date localChange = downloadService.getLastStateChanged(); - if(localChange == null || localChange.before(remoteChange)) { - playerQueue = remoteState; - } - } - } catch (Exception e) { - Log.e(TAG, "Failed to get playing queue to server", e); - } + // If we had a remote state and it's changed is more recent than our existing state + if(remoteState != null && remoteState.changed != null) { + // Check if changed + 30 seconds since some servers have slight skew + Date remoteChange = new Date(remoteState.changed.getTime() - ALLOWED_SKEW); + Date localChange = downloadService.getLastStateChanged(); + if(localChange == null || localChange.before(remoteChange)) { + playerQueue = remoteState; + } + } + } catch (Exception e) { + Log.e(TAG, "Failed to get playing queue to server", e); + } - return null; - } - }.execute(); - } + return null; + } + }.execute(); + } - private void createAccount() { - final Context context = this; + private void createAccount() { + final Context context = this; - new SilentBackgroundTask(this) { - @Override - protected Void doInBackground() throws Throwable { - AccountManager accountManager = (AccountManager) context.getSystemService(ACCOUNT_SERVICE); - Account account = new Account(Constants.SYNC_ACCOUNT_NAME, Constants.SYNC_ACCOUNT_TYPE); - accountManager.addAccountExplicitly(account, null, null); + new SilentBackgroundTask(this) { + @Override + protected Void doInBackground() throws Throwable { + AccountManager accountManager = (AccountManager) context.getSystemService(ACCOUNT_SERVICE); + Account account = new Account(Constants.SYNC_ACCOUNT_NAME, Constants.SYNC_ACCOUNT_TYPE); + accountManager.addAccountExplicitly(account, null, null); - SharedPreferences prefs = Util.getPreferences(context); - boolean syncEnabled = prefs.getBoolean(Constants.PREFERENCES_KEY_SYNC_ENABLED, true); - int syncInterval = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_SYNC_INTERVAL, "60")); + SharedPreferences prefs = Util.getPreferences(context); + boolean syncEnabled = prefs.getBoolean(Constants.PREFERENCES_KEY_SYNC_ENABLED, true); + int syncInterval = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_SYNC_INTERVAL, "60")); - // Add enabled/frequency to playlist syncing - ContentResolver.setSyncAutomatically(account, Constants.SYNC_ACCOUNT_PLAYLIST_AUTHORITY, syncEnabled); - ContentResolver.addPeriodicSync(account, Constants.SYNC_ACCOUNT_PLAYLIST_AUTHORITY, new Bundle(), 60L * syncInterval); + // Add enabled/frequency to playlist syncing + ContentResolver.setSyncAutomatically(account, Constants.SYNC_ACCOUNT_PLAYLIST_AUTHORITY, syncEnabled); + ContentResolver.addPeriodicSync(account, Constants.SYNC_ACCOUNT_PLAYLIST_AUTHORITY, new Bundle(), 60L * syncInterval); - return null; - } + return null; + } - @Override - protected void done(Void result) { + @Override + protected void done(Void result) { - } - }.execute(); - } + } + }.execute(); + } - private void showInfoDialog() { - if (!infoDialogDisplayed) { - infoDialogDisplayed = true; - if (Util.getRestUrl(this, null).contains("demo.subsonic.org")) { - Util.info(this, R.string.main_welcome_title, R.string.main_welcome_text); - } - } - } + private void showInfoDialog() { + if (!infoDialogDisplayed) { + infoDialogDisplayed = true; + if (Util.getRestUrl(this, null).contains("demo.subsonic.org")) { + Util.info(this, R.string.main_welcome_title, R.string.main_welcome_text); + } + } + } - public Toolbar getActiveToolbar() { - return slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED ? nowPlayingToolbar : mainToolbar; - } + public Toolbar getActiveToolbar() { + return slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.EXPANDED ? nowPlayingToolbar : mainToolbar; + } - @Override - public void onSongChanged(DownloadFile currentPlaying, int currentPlayingIndex) { - this.currentPlaying = currentPlaying; + @Override + public void onSongChanged(DownloadFile currentPlaying, int currentPlayingIndex) { + this.currentPlaying = currentPlaying; - MusicDirectory.Entry song = null; - if (currentPlaying != null) { - song = currentPlaying.getSong(); - trackView.setText(song.getTitle()); + MusicDirectory.Entry song = null; + if (currentPlaying != null) { + song = currentPlaying.getSong(); + trackView.setText(song.getTitle()); - if(song.getArtist() != null) { - artistView.setVisibility(View.VISIBLE); - artistView.setText(song.getArtist()); - } else { - artistView.setVisibility(View.GONE); - } - } else { - trackView.setText(R.string.main_title); - artistView.setText(R.string.main_artist); - } + if(song.getArtist() != null) { + artistView.setVisibility(View.VISIBLE); + artistView.setText(song.getArtist()); + } else { + artistView.setVisibility(View.GONE); + } + } else { + trackView.setText(R.string.main_title); + artistView.setText(R.string.main_artist); + } - if (coverArtView != null) { - int height = coverArtView.getHeight(); - if (height <= 0) { - int[] attrs = new int[]{R.attr.actionBarSize}; - TypedArray typedArray = this.obtainStyledAttributes(attrs); - height = typedArray.getDimensionPixelSize(0, 0); - typedArray.recycle(); - } - getImageLoader().loadImage(coverArtView, song, false, height, false); - } + if (coverArtView != null) { + int height = coverArtView.getHeight(); + if (height <= 0) { + int[] attrs = new int[]{R.attr.actionBarSize}; + TypedArray typedArray = this.obtainStyledAttributes(attrs); + height = typedArray.getDimensionPixelSize(0, 0); + typedArray.recycle(); + } + getImageLoader().loadImage(coverArtView, song, false, height, false); + } previousButton.setVisibility(View.VISIBLE); nextButton.setVisibility(View.VISIBLE); rewindButton.setVisibility(View.GONE); fastforwardButton.setVisibility(View.GONE); - } + } - @Override - public void onSongsChanged(List songs, DownloadFile currentPlaying, int currentPlayingIndex) { - if(this.currentPlaying != currentPlaying || this.currentPlaying == null) { - onSongChanged(currentPlaying, currentPlayingIndex); - } - } + @Override + public void onSongsChanged(List songs, DownloadFile currentPlaying, int currentPlayingIndex) { + if(this.currentPlaying != currentPlaying || this.currentPlaying == null) { + onSongChanged(currentPlaying, currentPlayingIndex); + } + } - @Override - public void onSongProgress(DownloadFile currentPlaying, int millisPlayed, Integer duration, boolean isSeekable) { + @Override + public void onSongProgress(DownloadFile currentPlaying, int millisPlayed, Integer duration, boolean isSeekable) { - } + } - @Override - public void onStateUpdate(DownloadFile downloadFile, PlayerState playerState) { - int[] attrs = new int[]{(playerState == PlayerState.STARTED) ? R.attr.actionbar_pause : R.attr.actionbar_start}; - TypedArray typedArray = this.obtainStyledAttributes(attrs); - startButton.setImageResource(typedArray.getResourceId(0, 0)); - typedArray.recycle(); - } + @Override + public void onStateUpdate(DownloadFile downloadFile, PlayerState playerState) { + int[] attrs = new int[]{(playerState == PlayerState.STARTED) ? R.attr.actionbar_pause : R.attr.actionbar_start}; + TypedArray typedArray = this.obtainStyledAttributes(attrs); + startButton.setImageResource(typedArray.getResourceId(0, 0)); + typedArray.recycle(); + } - @Override - public void onMetadataUpdate(MusicDirectory.Entry song, int fieldChange) { - if(song != null && coverArtView != null && fieldChange == DownloadService.METADATA_UPDATED_COVER_ART) { - int height = coverArtView.getHeight(); - if (height <= 0) { - int[] attrs = new int[]{R.attr.actionBarSize}; - TypedArray typedArray = this.obtainStyledAttributes(attrs); - height = typedArray.getDimensionPixelSize(0, 0); - typedArray.recycle(); - } - getImageLoader().loadImage(coverArtView, song, false, height, false); + @Override + public void onMetadataUpdate(MusicDirectory.Entry song, int fieldChange) { + if(song != null && coverArtView != null && fieldChange == DownloadService.METADATA_UPDATED_COVER_ART) { + int height = coverArtView.getHeight(); + if (height <= 0) { + int[] attrs = new int[]{R.attr.actionBarSize}; + TypedArray typedArray = this.obtainStyledAttributes(attrs); + height = typedArray.getDimensionPixelSize(0, 0); + typedArray.recycle(); + } + getImageLoader().loadImage(coverArtView, song, false, height, false); - // We need to update it immediately since it won't update if updater is not running for it - if(nowPlayingFragment != null && slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) { - nowPlayingFragment.onMetadataUpdate(song, fieldChange); - } - } - } + // We need to update it immediately since it won't update if updater is not running for it + if(nowPlayingFragment != null && slideUpPanel.getPanelState() == SlidingUpPanelLayout.PanelState.COLLAPSED) { + nowPlayingFragment.onMetadataUpdate(song, fieldChange); + } + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/activity/VoiceQueryReceiverActivity.java b/app/src/main/java/net/nullsum/audinaut/activity/VoiceQueryReceiverActivity.java index 49a199b..9aea6a1 100644 --- a/app/src/main/java/net/nullsum/audinaut/activity/VoiceQueryReceiverActivity.java +++ b/app/src/main/java/net/nullsum/audinaut/activity/VoiceQueryReceiverActivity.java @@ -40,7 +40,7 @@ import net.nullsum.audinaut.provider.AudinautSearchProvider; * @author Sindre Mehus */ public class VoiceQueryReceiverActivity extends Activity { - private static final String TAG = VoiceQueryReceiverActivity.class.getSimpleName(); + private static final String TAG = VoiceQueryReceiverActivity.class.getSimpleName(); @Override public void onCreate(Bundle savedInstanceState) { @@ -53,7 +53,7 @@ public class VoiceQueryReceiverActivity extends Activity { intent.putExtra(Constants.INTENT_EXTRA_NAME_QUERY, query); intent.putExtra(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true); intent.putExtra(MediaStore.EXTRA_MEDIA_FOCUS, getIntent().getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS)); - intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); + intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); Util.startActivityWithoutTransition(VoiceQueryReceiverActivity.this, intent); } finish(); diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/AlphabeticalAlbumAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/AlphabeticalAlbumAdapter.java index b494778..e91fdd2 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/AlphabeticalAlbumAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/AlphabeticalAlbumAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -24,21 +24,21 @@ import net.nullsum.audinaut.util.ImageLoader; import net.nullsum.audinaut.view.FastScroller; public class AlphabeticalAlbumAdapter extends EntryInfiniteGridAdapter implements FastScroller.BubbleTextGetter { - public AlphabeticalAlbumAdapter(Context context, List entries, ImageLoader imageLoader, boolean largeCell) { - super(context, entries, imageLoader, largeCell); - } + public AlphabeticalAlbumAdapter(Context context, List entries, ImageLoader imageLoader, boolean largeCell) { + super(context, entries, imageLoader, largeCell); + } - @Override - public String getTextToShowInBubble(int position) { - // Make sure that we are not trying to get an item for the loading placeholder - if(position >= sections.get(0).size()) { - if(sections.get(0).size() > 0) { - return getTextToShowInBubble(position - 1); - } else { - return "*"; - } - } else { - return getNameIndex(getItemForPosition(position).getAlbum()); - } - } + @Override + public String getTextToShowInBubble(int position) { + // Make sure that we are not trying to get an item for the loading placeholder + if(position >= sections.get(0).size()) { + if(sections.get(0).size() > 0) { + return getTextToShowInBubble(position - 1); + } else { + return "*"; + } + } else { + return getNameIndex(getItemForPosition(position).getAlbum()); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/ArtistAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/ArtistAdapter.java index e13234c..64a98ed 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/ArtistAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/ArtistAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -38,125 +38,125 @@ import net.nullsum.audinaut.view.SongView; import net.nullsum.audinaut.view.UpdateView; public class ArtistAdapter extends SectionAdapter implements FastScroller.BubbleTextGetter { - public static int VIEW_TYPE_SONG = 3; - public static int VIEW_TYPE_ARTIST = 4; + public static int VIEW_TYPE_SONG = 3; + public static int VIEW_TYPE_ARTIST = 4; - private List musicFolders; - private OnMusicFolderChanged onMusicFolderChanged; + private List musicFolders; + private OnMusicFolderChanged onMusicFolderChanged; - public ArtistAdapter(Context context, List artists, OnItemClickedListener listener) { - this(context, artists, null, listener, null); - } + public ArtistAdapter(Context context, List artists, OnItemClickedListener listener) { + this(context, artists, null, listener, null); + } - public ArtistAdapter(Context context, List artists, List musicFolders, OnItemClickedListener onItemClickedListener, OnMusicFolderChanged onMusicFolderChanged) { - super(context, artists); - this.musicFolders = musicFolders; - this.onItemClickedListener = onItemClickedListener; - this.onMusicFolderChanged = onMusicFolderChanged; + public ArtistAdapter(Context context, List artists, List musicFolders, OnItemClickedListener onItemClickedListener, OnMusicFolderChanged onMusicFolderChanged) { + super(context, artists); + this.musicFolders = musicFolders; + this.onItemClickedListener = onItemClickedListener; + this.onMusicFolderChanged = onMusicFolderChanged; - if(musicFolders != null) { - this.singleSectionHeader = true; - } - } + if(musicFolders != null) { + this.singleSectionHeader = true; + } + } - @Override - public UpdateView.UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { - final View header = LayoutInflater.from(context).inflate(R.layout.select_artist_header, parent, false); - header.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - PopupMenu popup = new PopupMenu(context, header.findViewById(R.id.select_artist_folder_2)); + @Override + public UpdateView.UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { + final View header = LayoutInflater.from(context).inflate(R.layout.select_artist_header, parent, false); + header.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + PopupMenu popup = new PopupMenu(context, header.findViewById(R.id.select_artist_folder_2)); - popup.getMenu().add(R.string.select_artist_all_folders); - for (MusicFolder musicFolder : musicFolders) { - popup.getMenu().add(musicFolder.getName()); - } + popup.getMenu().add(R.string.select_artist_all_folders); + for (MusicFolder musicFolder : musicFolders) { + popup.getMenu().add(musicFolder.getName()); + } - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - for (MusicFolder musicFolder : musicFolders) { - if(item.getTitle().equals(musicFolder.getName())) { - if(onMusicFolderChanged != null) { - onMusicFolderChanged.onMusicFolderChanged(musicFolder); - } - return true; - } - } + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + for (MusicFolder musicFolder : musicFolders) { + if(item.getTitle().equals(musicFolder.getName())) { + if(onMusicFolderChanged != null) { + onMusicFolderChanged.onMusicFolderChanged(musicFolder); + } + return true; + } + } - if(onMusicFolderChanged != null) { - onMusicFolderChanged.onMusicFolderChanged(null); - } - return true; - } - }); - popup.show(); - } - }); + if(onMusicFolderChanged != null) { + onMusicFolderChanged.onMusicFolderChanged(null); + } + return true; + } + }); + popup.show(); + } + }); - return new UpdateView.UpdateViewHolder(header, false); - } - @Override - public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String header, int sectionIndex) { - TextView folderName = (TextView) holder.getView().findViewById(R.id.select_artist_folder_2); + return new UpdateView.UpdateViewHolder(header, false); + } + @Override + public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String header, int sectionIndex) { + TextView folderName = (TextView) holder.getView().findViewById(R.id.select_artist_folder_2); - String musicFolderId = Util.getSelectedMusicFolderId(context); - if(musicFolderId != null) { - for (MusicFolder musicFolder : musicFolders) { - if (musicFolder.getId().equals(musicFolderId)) { - folderName.setText(musicFolder.getName()); - break; - } - } - } else { - folderName.setText(R.string.select_artist_all_folders); - } - } + String musicFolderId = Util.getSelectedMusicFolderId(context); + if(musicFolderId != null) { + for (MusicFolder musicFolder : musicFolders) { + if (musicFolder.getId().equals(musicFolderId)) { + folderName.setText(musicFolder.getName()); + break; + } + } + } else { + folderName.setText(R.string.select_artist_all_folders); + } + } - @Override - public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - UpdateView updateView = null; - if(viewType == VIEW_TYPE_ARTIST) { - updateView = new ArtistView(context); - } else if(viewType == VIEW_TYPE_SONG) { - updateView = new SongView(context); - } + @Override + public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + UpdateView updateView = null; + if(viewType == VIEW_TYPE_ARTIST) { + updateView = new ArtistView(context); + } else if(viewType == VIEW_TYPE_SONG) { + updateView = new SongView(context); + } - return new UpdateView.UpdateViewHolder(updateView); - } + return new UpdateView.UpdateViewHolder(updateView); + } - @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Serializable item, int viewType) { - UpdateView view = holder.getUpdateView(); - if(viewType == VIEW_TYPE_ARTIST) { - view.setObject(item); - } else if(viewType == VIEW_TYPE_SONG) { - SongView songView = (SongView) view; - Entry entry = (Entry) item; - songView.setObject(entry, checkable); - } - } + @Override + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Serializable item, int viewType) { + UpdateView view = holder.getUpdateView(); + if(viewType == VIEW_TYPE_ARTIST) { + view.setObject(item); + } else if(viewType == VIEW_TYPE_SONG) { + SongView songView = (SongView) view; + Entry entry = (Entry) item; + songView.setObject(entry, checkable); + } + } - @Override - public int getItemViewType(Serializable item) { - if(item instanceof Artist) { - return VIEW_TYPE_ARTIST; - } else { - return VIEW_TYPE_SONG; - } - } + @Override + public int getItemViewType(Serializable item) { + if(item instanceof Artist) { + return VIEW_TYPE_ARTIST; + } else { + return VIEW_TYPE_SONG; + } + } - @Override - public String getTextToShowInBubble(int position) { - Object item = getItemForPosition(position); - if(item instanceof Artist) { - return getNameIndex(((Artist) item).getName(), true); - } else { - return null; - } - } + @Override + public String getTextToShowInBubble(int position) { + Object item = getItemForPosition(position); + if(item instanceof Artist) { + return getNameIndex(((Artist) item).getName(), true); + } else { + return null; + } + } - public interface OnMusicFolderChanged { - void onMusicFolderChanged(MusicFolder musicFolder); - } + public interface OnMusicFolderChanged { + void onMusicFolderChanged(MusicFolder musicFolder); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/BasicListAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/BasicListAdapter.java index b3743f4..ae04bca 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/BasicListAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/BasicListAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -24,25 +24,25 @@ import net.nullsum.audinaut.view.BasicListView; import net.nullsum.audinaut.view.UpdateView; public class BasicListAdapter extends SectionAdapter { - public static int VIEW_TYPE_LINE = 1; + public static int VIEW_TYPE_LINE = 1; - public BasicListAdapter(Context context, List strings, OnItemClickedListener listener) { - super(context, strings); - this.onItemClickedListener = listener; - } + public BasicListAdapter(Context context, List strings, OnItemClickedListener listener) { + super(context, strings); + this.onItemClickedListener = listener; + } - @Override - public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - return new UpdateView.UpdateViewHolder(new BasicListView(context)); - } + @Override + public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + return new UpdateView.UpdateViewHolder(new BasicListView(context)); + } - @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, String item, int viewType) { - holder.getUpdateView().setObject(item); - } + @Override + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, String item, int viewType) { + holder.getUpdateView().setObject(item); + } - @Override - public int getItemViewType(String item) { - return VIEW_TYPE_LINE; - } + @Override + public int getItemViewType(String item) { + return VIEW_TYPE_LINE; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/DetailsAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/DetailsAdapter.java index e1828b7..dcb03f1 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/DetailsAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/DetailsAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -30,33 +30,33 @@ import java.util.List; import net.nullsum.audinaut.R; public class DetailsAdapter extends ArrayAdapter { - private List headers; - private List details; + private List headers; + private List details; - public DetailsAdapter(Context context, int layout, List headers, List details) { - super(context, layout, headers); + public DetailsAdapter(Context context, int layout, List headers, List details) { + super(context, layout, headers); - this.headers = headers; - this.details = details; - } + this.headers = headers; + this.details = details; + } - @Override - public View getView(int position, View convertView, ViewGroup parent){ - View view; - if(convertView == null) { - view = LayoutInflater.from(getContext()).inflate(R.layout.details_item, null); - } else { - view = convertView; - } + @Override + public View getView(int position, View convertView, ViewGroup parent){ + View view; + if(convertView == null) { + view = LayoutInflater.from(getContext()).inflate(R.layout.details_item, null); + } else { + view = convertView; + } - TextView nameView = (TextView) view.findViewById(R.id.detail_name); - TextView detailsView = (TextView) view.findViewById(R.id.detail_value); + TextView nameView = (TextView) view.findViewById(R.id.detail_name); + TextView detailsView = (TextView) view.findViewById(R.id.detail_value); - nameView.setText(headers.get(position)); + nameView.setText(headers.get(position)); - detailsView.setText(details.get(position)); - Linkify.addLinks(detailsView, Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES); + detailsView.setText(details.get(position)); + Linkify.addLinks(detailsView, Linkify.WEB_URLS | Linkify.EMAIL_ADDRESSES); - return view; - } + return view; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/DownloadFileAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/DownloadFileAdapter.java index e127ae5..6a1d1dc 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/DownloadFileAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/DownloadFileAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -33,42 +33,42 @@ import net.nullsum.audinaut.view.SongView; import net.nullsum.audinaut.view.UpdateView; public class DownloadFileAdapter extends SectionAdapter implements FastScroller.BubbleTextGetter { - public static int VIEW_TYPE_DOWNLOAD_FILE = 1; + public static int VIEW_TYPE_DOWNLOAD_FILE = 1; - public DownloadFileAdapter(Context context, List entries, OnItemClickedListener onItemClickedListener) { - super(context, entries); - this.onItemClickedListener = onItemClickedListener; - this.checkable = true; - } + public DownloadFileAdapter(Context context, List entries, OnItemClickedListener onItemClickedListener) { + super(context, entries); + this.onItemClickedListener = onItemClickedListener; + this.checkable = true; + } - @Override - public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - return new UpdateView.UpdateViewHolder(new SongView(context)); - } + @Override + public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + return new UpdateView.UpdateViewHolder(new SongView(context)); + } - @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, DownloadFile item, int viewType) { - SongView songView = (SongView) holder.getUpdateView(); - songView.setObject(item.getSong(), Util.isBatchMode(context)); - songView.setDownloadFile(item); - } + @Override + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, DownloadFile item, int viewType) { + SongView songView = (SongView) holder.getUpdateView(); + songView.setObject(item.getSong(), Util.isBatchMode(context)); + songView.setDownloadFile(item); + } - @Override - public int getItemViewType(DownloadFile item) { - return VIEW_TYPE_DOWNLOAD_FILE; - } + @Override + public int getItemViewType(DownloadFile item) { + return VIEW_TYPE_DOWNLOAD_FILE; + } - @Override - public String getTextToShowInBubble(int position) { - return null; - } + @Override + public String getTextToShowInBubble(int position) { + return null; + } - @Override - public void onCreateActionModeMenu(Menu menu, MenuInflater menuInflater) { - if(Util.isOffline(context)) { - menuInflater.inflate(R.menu.multiselect_nowplaying_offline, menu); - } else { - menuInflater.inflate(R.menu.multiselect_nowplaying, menu); - } - } + @Override + public void onCreateActionModeMenu(Menu menu, MenuInflater menuInflater) { + if(Util.isOffline(context)) { + menuInflater.inflate(R.menu.multiselect_nowplaying_offline, menu); + } else { + menuInflater.inflate(R.menu.multiselect_nowplaying, menu); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/EntryGridAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/EntryGridAdapter.java index b301666..017dfa0 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/EntryGridAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/EntryGridAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -35,122 +35,122 @@ import net.nullsum.audinaut.view.UpdateView; import net.nullsum.audinaut.view.UpdateView.UpdateViewHolder; public class EntryGridAdapter extends SectionAdapter { - private static String TAG = EntryGridAdapter.class.getSimpleName(); + private static String TAG = EntryGridAdapter.class.getSimpleName(); - public static int VIEW_TYPE_ALBUM_CELL = 1; - public static int VIEW_TYPE_ALBUM_LINE = 2; - public static int VIEW_TYPE_SONG = 3; + public static int VIEW_TYPE_ALBUM_CELL = 1; + public static int VIEW_TYPE_ALBUM_LINE = 2; + public static int VIEW_TYPE_SONG = 3; - private ImageLoader imageLoader; - private boolean largeAlbums; - private boolean showArtist = false; - private boolean showAlbum = false; - private boolean removeFromPlaylist = false; - private View header; + private ImageLoader imageLoader; + private boolean largeAlbums; + private boolean showArtist = false; + private boolean showAlbum = false; + private boolean removeFromPlaylist = false; + private View header; - public EntryGridAdapter(Context context, List entries, ImageLoader imageLoader, boolean largeCell) { - super(context, entries); - this.imageLoader = imageLoader; - this.largeAlbums = largeCell; + public EntryGridAdapter(Context context, List entries, ImageLoader imageLoader, boolean largeCell) { + super(context, entries); + this.imageLoader = imageLoader; + this.largeAlbums = largeCell; - // Always show artist if they aren't all the same - String artist = null; - for(MusicDirectory.Entry entry: entries) { - if(artist == null) { - artist = entry.getArtist(); - } + // Always show artist if they aren't all the same + String artist = null; + for(MusicDirectory.Entry entry: entries) { + if(artist == null) { + artist = entry.getArtist(); + } - if(artist != null && !artist.equals(entry.getArtist())) { - showArtist = true; - } - } - checkable = true; - } + if(artist != null && !artist.equals(entry.getArtist())) { + showArtist = true; + } + } + checkable = true; + } - @Override - public UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - UpdateView updateView = null; - if(viewType == VIEW_TYPE_ALBUM_LINE || viewType == VIEW_TYPE_ALBUM_CELL) { - updateView = new AlbumView(context, viewType == VIEW_TYPE_ALBUM_CELL); - } else if(viewType == VIEW_TYPE_SONG) { - updateView = new SongView(context); - } + @Override + public UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + UpdateView updateView = null; + if(viewType == VIEW_TYPE_ALBUM_LINE || viewType == VIEW_TYPE_ALBUM_CELL) { + updateView = new AlbumView(context, viewType == VIEW_TYPE_ALBUM_CELL); + } else if(viewType == VIEW_TYPE_SONG) { + updateView = new SongView(context); + } - return new UpdateViewHolder(updateView); - } + return new UpdateViewHolder(updateView); + } - @Override - public void onBindViewHolder(UpdateViewHolder holder, Entry entry, int viewType) { - UpdateView view = holder.getUpdateView(); - if(viewType == VIEW_TYPE_ALBUM_CELL || viewType == VIEW_TYPE_ALBUM_LINE) { - AlbumView albumView = (AlbumView) view; - albumView.setShowArtist(showArtist); - albumView.setObject(entry, imageLoader); - } else if(viewType == VIEW_TYPE_SONG) { - SongView songView = (SongView) view; - songView.setShowAlbum(showAlbum); - songView.setObject(entry, checkable); - } - } + @Override + public void onBindViewHolder(UpdateViewHolder holder, Entry entry, int viewType) { + UpdateView view = holder.getUpdateView(); + if(viewType == VIEW_TYPE_ALBUM_CELL || viewType == VIEW_TYPE_ALBUM_LINE) { + AlbumView albumView = (AlbumView) view; + albumView.setShowArtist(showArtist); + albumView.setObject(entry, imageLoader); + } else if(viewType == VIEW_TYPE_SONG) { + SongView songView = (SongView) view; + songView.setShowAlbum(showAlbum); + songView.setObject(entry, checkable); + } + } - public UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { - return new UpdateViewHolder(header, false); - } - public void onBindHeaderHolder(UpdateViewHolder holder, String header, int sectionIndex) { + public UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { + return new UpdateViewHolder(header, false); + } + public void onBindHeaderHolder(UpdateViewHolder holder, String header, int sectionIndex) { - } + } - @Override - public int getItemViewType(Entry entry) { - if(entry.isDirectory()) { - if (largeAlbums) { - return VIEW_TYPE_ALBUM_CELL; - } else { - return VIEW_TYPE_ALBUM_LINE; - } - } else { - return VIEW_TYPE_SONG; - } - } + @Override + public int getItemViewType(Entry entry) { + if(entry.isDirectory()) { + if (largeAlbums) { + return VIEW_TYPE_ALBUM_CELL; + } else { + return VIEW_TYPE_ALBUM_LINE; + } + } else { + return VIEW_TYPE_SONG; + } + } - public void setHeader(View header) { - this.header = header; - this.singleSectionHeader = true; - } - public View getHeader() { - return header; - } + public void setHeader(View header) { + this.header = header; + this.singleSectionHeader = true; + } + public View getHeader() { + return header; + } - public void setShowArtist(boolean showArtist) { - this.showArtist = showArtist; - } + public void setShowArtist(boolean showArtist) { + this.showArtist = showArtist; + } - public void setShowAlbum(boolean showAlbum) { - this.showAlbum = showAlbum; - } + public void setShowAlbum(boolean showAlbum) { + this.showAlbum = showAlbum; + } - public void removeAt(int index) { - sections.get(0).remove(index); - if(header != null) { - index++; - } - notifyItemRemoved(index); - } + public void removeAt(int index) { + sections.get(0).remove(index); + if(header != null) { + index++; + } + notifyItemRemoved(index); + } - public void setRemoveFromPlaylist(boolean removeFromPlaylist) { - this.removeFromPlaylist = removeFromPlaylist; - } + public void setRemoveFromPlaylist(boolean removeFromPlaylist) { + this.removeFromPlaylist = removeFromPlaylist; + } - @Override - public void onCreateActionModeMenu(Menu menu, MenuInflater menuInflater) { - if(Util.isOffline(context)) { - menuInflater.inflate(R.menu.multiselect_media_offline, menu); - } else { - menuInflater.inflate(R.menu.multiselect_media, menu); - } + @Override + public void onCreateActionModeMenu(Menu menu, MenuInflater menuInflater) { + if(Util.isOffline(context)) { + menuInflater.inflate(R.menu.multiselect_media_offline, menu); + } else { + menuInflater.inflate(R.menu.multiselect_media, menu); + } - if(!removeFromPlaylist) { - menu.removeItem(R.id.menu_remove_playlist); - } - } + if(!removeFromPlaylist) { + menu.removeItem(R.id.menu_remove_playlist); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/EntryInfiniteGridAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/EntryInfiniteGridAdapter.java index 978458c..5af5066 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/EntryInfiniteGridAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/EntryInfiniteGridAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -33,120 +33,120 @@ import net.nullsum.audinaut.util.SilentBackgroundTask; import net.nullsum.audinaut.view.UpdateView; public class EntryInfiniteGridAdapter extends EntryGridAdapter { - public static int VIEW_TYPE_LOADING = 4; + public static int VIEW_TYPE_LOADING = 4; - private String type; - private String extra; - private int size; + private String type; + private String extra; + private int size; - private boolean loading = false; - private boolean allLoaded = false; + private boolean loading = false; + private boolean allLoaded = false; - public EntryInfiniteGridAdapter(Context context, List entries, ImageLoader imageLoader, boolean largeCell) { - super(context, entries, imageLoader, largeCell); - } + public EntryInfiniteGridAdapter(Context context, List entries, ImageLoader imageLoader, boolean largeCell) { + super(context, entries, imageLoader, largeCell); + } - @Override - public UpdateView.UpdateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - if(viewType == VIEW_TYPE_LOADING) { - View progress = LayoutInflater.from(context).inflate(R.layout.tab_progress, null); - progress.setVisibility(View.VISIBLE); - return new UpdateView.UpdateViewHolder(progress, false); - } + @Override + public UpdateView.UpdateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if(viewType == VIEW_TYPE_LOADING) { + View progress = LayoutInflater.from(context).inflate(R.layout.tab_progress, null); + progress.setVisibility(View.VISIBLE); + return new UpdateView.UpdateViewHolder(progress, false); + } - return super.onCreateViewHolder(parent, viewType); - } + return super.onCreateViewHolder(parent, viewType); + } - @Override - public int getItemViewType(int position) { - if(isLoadingView(position)) { - return VIEW_TYPE_LOADING; - } + @Override + public int getItemViewType(int position) { + if(isLoadingView(position)) { + return VIEW_TYPE_LOADING; + } - return super.getItemViewType(position); - } + return super.getItemViewType(position); + } - @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, int position) { - if(!isLoadingView(position)) { - super.onBindViewHolder(holder, position); - } - } + @Override + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, int position) { + if(!isLoadingView(position)) { + super.onBindViewHolder(holder, position); + } + } - @Override - public int getItemCount() { - int size = super.getItemCount(); + @Override + public int getItemCount() { + int size = super.getItemCount(); - if(!allLoaded) { - size++; - } + if(!allLoaded) { + size++; + } - return size; - } + return size; + } - public void setData(String type, String extra, int size) { - this.type = type; - this.extra = extra; - this.size = size; + public void setData(String type, String extra, int size) { + this.type = type; + this.extra = extra; + this.size = size; - if(super.getItemCount() < size) { - allLoaded = true; - } - } + if(super.getItemCount() < size) { + allLoaded = true; + } + } - public void loadMore() { - if(loading || allLoaded) { - return; - } - loading = true; + public void loadMore() { + if(loading || allLoaded) { + return; + } + loading = true; - new SilentBackgroundTask(context) { - private List newData; + new SilentBackgroundTask(context) { + private List newData; - @Override - protected Void doInBackground() throws Throwable { - newData = cacheInBackground(); - return null; - } + @Override + protected Void doInBackground() throws Throwable { + newData = cacheInBackground(); + return null; + } - @Override - protected void done(Void result) { - appendCachedData(newData); - loading = false; + @Override + protected void done(Void result) { + appendCachedData(newData); + loading = false; - if(newData.size() < size) { - allLoaded = true; - notifyDataSetChanged(); - } - } - }.execute(); - } + if(newData.size() < size) { + allLoaded = true; + notifyDataSetChanged(); + } + } + }.execute(); + } - protected List cacheInBackground() throws Exception { - MusicService service = MusicServiceFactory.getMusicService(context); - MusicDirectory result; - int offset = sections.get(0).size(); - if("genres".equals(type) || "years".equals(type)) { - result = service.getAlbumList(type, extra, size, offset, false, context, null); - } else if("genres".equals(type) || "genres-songs".equals(type)) { - result = service.getSongsByGenre(extra, size, offset, context, null); - }else if(type.indexOf(MainFragment.SONGS_LIST_PREFIX) != -1) { - result = service.getSongList(type, size, offset, context, null); - } else { - result = service.getAlbumList(type, size, offset, false, context, null); - } - return result.getChildren(); - } + protected List cacheInBackground() throws Exception { + MusicService service = MusicServiceFactory.getMusicService(context); + MusicDirectory result; + int offset = sections.get(0).size(); + if("genres".equals(type) || "years".equals(type)) { + result = service.getAlbumList(type, extra, size, offset, false, context, null); + } else if("genres".equals(type) || "genres-songs".equals(type)) { + result = service.getSongsByGenre(extra, size, offset, context, null); + }else if(type.indexOf(MainFragment.SONGS_LIST_PREFIX) != -1) { + result = service.getSongList(type, size, offset, context, null); + } else { + result = service.getAlbumList(type, size, offset, false, context, null); + } + return result.getChildren(); + } - protected void appendCachedData(List newData) { - if(newData.size() > 0) { - int start = sections.get(0).size(); - sections.get(0).addAll(newData); - this.notifyItemRangeInserted(start, newData.size()); - } - } + protected void appendCachedData(List newData) { + if(newData.size() > 0) { + int start = sections.get(0).size(); + sections.get(0).addAll(newData); + this.notifyItemRangeInserted(start, newData.size()); + } + } - protected boolean isLoadingView(int position) { - return !allLoaded && position >= sections.get(0).size(); - } + protected boolean isLoadingView(int position) { + return !allLoaded && position >= sections.get(0).size(); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/ExpandableSectionAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/ExpandableSectionAdapter.java index 1b44cb1..7212496 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/ExpandableSectionAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/ExpandableSectionAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -31,120 +31,120 @@ import net.nullsum.audinaut.view.BasicHeaderView; import net.nullsum.audinaut.view.UpdateView; public abstract class ExpandableSectionAdapter extends SectionAdapter { - private static final String TAG = ExpandableSectionAdapter.class.getSimpleName(); - private static final int DEFAULT_VISIBLE = 4; - private static final int EXPAND_TOGGLE = R.attr.select_server; - private static final int COLLAPSE_TOGGLE = R.attr.select_tabs; + private static final String TAG = ExpandableSectionAdapter.class.getSimpleName(); + private static final int DEFAULT_VISIBLE = 4; + private static final int EXPAND_TOGGLE = R.attr.select_server; + private static final int COLLAPSE_TOGGLE = R.attr.select_tabs; - protected List sectionsDefaultVisible; - protected List> sectionsExtras; - protected int expandToggleRes; - protected int collapseToggleRes; + protected List sectionsDefaultVisible; + protected List> sectionsExtras; + protected int expandToggleRes; + protected int collapseToggleRes; - protected ExpandableSectionAdapter() {} - public ExpandableSectionAdapter(Context context, List section) { - List> sections = new ArrayList<>(); - sections.add(section); + protected ExpandableSectionAdapter() {} + public ExpandableSectionAdapter(Context context, List section) { + List> sections = new ArrayList<>(); + sections.add(section); - init(context, Arrays.asList("Section"), sections, Arrays.asList((Integer) null)); - } - public ExpandableSectionAdapter(Context context, List headers, List> sections) { - init(context, headers, sections, null); - } - public ExpandableSectionAdapter(Context context, List headers, List> sections, List sectionsDefaultVisible) { - init(context, headers, sections, sectionsDefaultVisible); - } - protected void init(Context context, List headers, List> fullSections, List sectionsDefaultVisible) { - this.context = context; - this.headers = headers; - this.sectionsDefaultVisible = sectionsDefaultVisible; - if(sectionsDefaultVisible == null) { - sectionsDefaultVisible = new ArrayList<>(fullSections.size()); - for(int i = 0; i < fullSections.size(); i++) { - sectionsDefaultVisible.add(DEFAULT_VISIBLE); - } - } + init(context, Arrays.asList("Section"), sections, Arrays.asList((Integer) null)); + } + public ExpandableSectionAdapter(Context context, List headers, List> sections) { + init(context, headers, sections, null); + } + public ExpandableSectionAdapter(Context context, List headers, List> sections, List sectionsDefaultVisible) { + init(context, headers, sections, sectionsDefaultVisible); + } + protected void init(Context context, List headers, List> fullSections, List sectionsDefaultVisible) { + this.context = context; + this.headers = headers; + this.sectionsDefaultVisible = sectionsDefaultVisible; + if(sectionsDefaultVisible == null) { + sectionsDefaultVisible = new ArrayList<>(fullSections.size()); + for(int i = 0; i < fullSections.size(); i++) { + sectionsDefaultVisible.add(DEFAULT_VISIBLE); + } + } - this.sections = new ArrayList<>(); - this.sectionsExtras = new ArrayList<>(); - int i = 0; - for(List fullSection: fullSections) { - List visibleSection = new ArrayList<>(); + this.sections = new ArrayList<>(); + this.sectionsExtras = new ArrayList<>(); + int i = 0; + for(List fullSection: fullSections) { + List visibleSection = new ArrayList<>(); - Integer defaultVisible = sectionsDefaultVisible.get(i); - if(defaultVisible == null || defaultVisible >= fullSection.size()) { - visibleSection.addAll(fullSection); - this.sectionsExtras.add(null); - } else { - visibleSection.addAll(fullSection.subList(0, defaultVisible)); - this.sectionsExtras.add(fullSection.subList(defaultVisible, fullSection.size())); - } - this.sections.add(visibleSection); + Integer defaultVisible = sectionsDefaultVisible.get(i); + if(defaultVisible == null || defaultVisible >= fullSection.size()) { + visibleSection.addAll(fullSection); + this.sectionsExtras.add(null); + } else { + visibleSection.addAll(fullSection.subList(0, defaultVisible)); + this.sectionsExtras.add(fullSection.subList(defaultVisible, fullSection.size())); + } + this.sections.add(visibleSection); - i++; - } + i++; + } - expandToggleRes = DrawableTint.getDrawableRes(context, EXPAND_TOGGLE); - collapseToggleRes = DrawableTint.getDrawableRes(context, COLLAPSE_TOGGLE); - } + expandToggleRes = DrawableTint.getDrawableRes(context, EXPAND_TOGGLE); + collapseToggleRes = DrawableTint.getDrawableRes(context, COLLAPSE_TOGGLE); + } - @Override - public UpdateView.UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { - return new UpdateView.UpdateViewHolder(new BasicHeaderView(context, R.layout.expandable_header)); - } + @Override + public UpdateView.UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { + return new UpdateView.UpdateViewHolder(new BasicHeaderView(context, R.layout.expandable_header)); + } - @Override - public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String header, final int sectionIndex) { - UpdateView view = holder.getUpdateView(); - ImageView toggleSelectionView = (ImageView) view.findViewById(R.id.item_select); + @Override + public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String header, final int sectionIndex) { + UpdateView view = holder.getUpdateView(); + ImageView toggleSelectionView = (ImageView) view.findViewById(R.id.item_select); - List visibleSelection = sections.get(sectionIndex); - List sectionExtras = sectionsExtras.get(sectionIndex); + List visibleSelection = sections.get(sectionIndex); + List sectionExtras = sectionsExtras.get(sectionIndex); - if(sectionExtras != null && !sectionExtras.isEmpty()) { - toggleSelectionView.setVisibility(View.VISIBLE); - toggleSelectionView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - List visibleSelection = sections.get(sectionIndex); - List sectionExtras = sectionsExtras.get(sectionIndex); + if(sectionExtras != null && !sectionExtras.isEmpty()) { + toggleSelectionView.setVisibility(View.VISIBLE); + toggleSelectionView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + List visibleSelection = sections.get(sectionIndex); + List sectionExtras = sectionsExtras.get(sectionIndex); - // Update icon - int selectToggleAttr; - if (!visibleSelection.contains(sectionExtras.get(0))) { - selectToggleAttr = COLLAPSE_TOGGLE; + // Update icon + int selectToggleAttr; + if (!visibleSelection.contains(sectionExtras.get(0))) { + selectToggleAttr = COLLAPSE_TOGGLE; - // Update how many are displayed - int lastIndex = getItemPosition(visibleSelection.get(visibleSelection.size() - 1)); - visibleSelection.addAll(sectionExtras); - notifyItemRangeInserted(lastIndex, sectionExtras.size()); - } else { - selectToggleAttr = EXPAND_TOGGLE; + // Update how many are displayed + int lastIndex = getItemPosition(visibleSelection.get(visibleSelection.size() - 1)); + visibleSelection.addAll(sectionExtras); + notifyItemRangeInserted(lastIndex, sectionExtras.size()); + } else { + selectToggleAttr = EXPAND_TOGGLE; - // Update how many are displayed - visibleSelection.removeAll(sectionExtras); - int lastIndex = getItemPosition(visibleSelection.get(visibleSelection.size() - 1)); - notifyItemRangeRemoved(lastIndex, sectionExtras.size()); - } + // Update how many are displayed + visibleSelection.removeAll(sectionExtras); + int lastIndex = getItemPosition(visibleSelection.get(visibleSelection.size() - 1)); + notifyItemRangeRemoved(lastIndex, sectionExtras.size()); + } - ((ImageView) v).setImageResource(DrawableTint.getDrawableRes(context, selectToggleAttr)); - } - }); + ((ImageView) v).setImageResource(DrawableTint.getDrawableRes(context, selectToggleAttr)); + } + }); - int selectToggleAttr; - if (!visibleSelection.contains(sectionExtras.get(0))) { - selectToggleAttr = EXPAND_TOGGLE; - } else { - selectToggleAttr = COLLAPSE_TOGGLE; - } + int selectToggleAttr; + if (!visibleSelection.contains(sectionExtras.get(0))) { + selectToggleAttr = EXPAND_TOGGLE; + } else { + selectToggleAttr = COLLAPSE_TOGGLE; + } - toggleSelectionView.setImageResource(DrawableTint.getDrawableRes(context, selectToggleAttr)); - } else { - toggleSelectionView.setVisibility(View.GONE); - } + toggleSelectionView.setImageResource(DrawableTint.getDrawableRes(context, selectToggleAttr)); + } else { + toggleSelectionView.setVisibility(View.GONE); + } - if(view != null) { - view.setObject(header); - } - } + if(view != null) { + view.setObject(header); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/GenreAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/GenreAdapter.java index d5158b6..eb9fab0 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/GenreAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/GenreAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -25,30 +25,30 @@ import net.nullsum.audinaut.view.UpdateView; import java.util.List; public class GenreAdapter extends SectionAdapter implements FastScroller.BubbleTextGetter{ - public static int VIEW_TYPE_GENRE = 1; + public static int VIEW_TYPE_GENRE = 1; - public GenreAdapter(Context context, List genres, OnItemClickedListener listener) { + public GenreAdapter(Context context, List genres, OnItemClickedListener listener) { super(context, genres); - this.onItemClickedListener = listener; + this.onItemClickedListener = listener; } - @Override - public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - return new UpdateView.UpdateViewHolder(new GenreView(context)); - } + @Override + public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + return new UpdateView.UpdateViewHolder(new GenreView(context)); + } - @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Genre item, int viewType) { - holder.getUpdateView().setObject(item); - } + @Override + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Genre item, int viewType) { + holder.getUpdateView().setObject(item); + } - @Override - public int getItemViewType(Genre item) { - return VIEW_TYPE_GENRE; - } + @Override + public int getItemViewType(Genre item) { + return VIEW_TYPE_GENRE; + } - @Override - public String getTextToShowInBubble(int position) { - return getNameIndex(getItemForPosition(position).getName()); - } + @Override + public String getTextToShowInBubble(int position) { + return getNameIndex(getItemForPosition(position).getName()); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/MainAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/MainAdapter.java index f185971..b44cdd4 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/MainAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/MainAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -30,55 +30,55 @@ import net.nullsum.audinaut.view.BasicListView; import net.nullsum.audinaut.view.UpdateView; public class MainAdapter extends SectionAdapter { - public static final int VIEW_TYPE_ALBUM_LIST = 1; + public static final int VIEW_TYPE_ALBUM_LIST = 1; - public MainAdapter(Context context, List headers, List> sections, OnItemClickedListener onItemClickedListener) { - super(context, headers, sections); - this.onItemClickedListener = onItemClickedListener; - } + public MainAdapter(Context context, List headers, List> sections, OnItemClickedListener onItemClickedListener) { + super(context, headers, sections); + this.onItemClickedListener = onItemClickedListener; + } - @Override - public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - UpdateView updateView = new BasicListView(context); - return new UpdateView.UpdateViewHolder(updateView); - } + @Override + public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + UpdateView updateView = new BasicListView(context); + return new UpdateView.UpdateViewHolder(updateView); + } - @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Integer item, int viewType) { - UpdateView updateView = holder.getUpdateView(); + @Override + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Integer item, int viewType) { + UpdateView updateView = holder.getUpdateView(); - if(viewType == VIEW_TYPE_ALBUM_LIST) { - updateView.setObject(context.getResources().getString(item)); - } else { - updateView.setObject(item); - } - } + if(viewType == VIEW_TYPE_ALBUM_LIST) { + updateView.setObject(context.getResources().getString(item)); + } else { + updateView.setObject(item); + } + } - @Override - public int getItemViewType(Integer item) { - return VIEW_TYPE_ALBUM_LIST; - } + @Override + public int getItemViewType(Integer item) { + return VIEW_TYPE_ALBUM_LIST; + } - @Override - public UpdateView.UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { - return new UpdateView.UpdateViewHolder(new BasicHeaderView(context, R.layout.album_list_header)); - } - @Override - public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String header, int sectionIndex) { - UpdateView view = holder.getUpdateView(); - CheckBox checkBox = (CheckBox) view.findViewById(R.id.item_checkbox); + @Override + public UpdateView.UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { + return new UpdateView.UpdateViewHolder(new BasicHeaderView(context, R.layout.album_list_header)); + } + @Override + public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String header, int sectionIndex) { + UpdateView view = holder.getUpdateView(); + CheckBox checkBox = (CheckBox) view.findViewById(R.id.item_checkbox); - String display; - if("songs".equals(header)) { - display = context.getResources().getString(R.string.search_songs); - checkBox.setVisibility(View.GONE); - } else { - display = header; - checkBox.setVisibility(View.GONE); - } + String display; + if("songs".equals(header)) { + display = context.getResources().getString(R.string.search_songs); + checkBox.setVisibility(View.GONE); + } else { + display = header; + checkBox.setVisibility(View.GONE); + } - if(view != null) { - view.setObject(display); - } - } + if(view != null) { + view.setObject(display); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/PlaylistAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/PlaylistAdapter.java index 961c439..94a48a4 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/PlaylistAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/PlaylistAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -26,47 +26,47 @@ import net.nullsum.audinaut.view.PlaylistView; import net.nullsum.audinaut.view.UpdateView; public class PlaylistAdapter extends SectionAdapter implements FastScroller.BubbleTextGetter { - public static int VIEW_TYPE_PLAYLIST = 1; + public static int VIEW_TYPE_PLAYLIST = 1; - private ImageLoader imageLoader; - private boolean largeCell; + private ImageLoader imageLoader; + private boolean largeCell; - public PlaylistAdapter(Context context, List playlists, ImageLoader imageLoader, boolean largeCell, OnItemClickedListener listener) { - super(context, playlists); - this.imageLoader = imageLoader; - this.largeCell = largeCell; - this.onItemClickedListener = listener; - } - public PlaylistAdapter(Context context, List headers, List> sections, ImageLoader imageLoader, boolean largeCell, OnItemClickedListener listener) { - super(context, headers, sections); - this.imageLoader = imageLoader; - this.largeCell = largeCell; - this.onItemClickedListener = listener; - } + public PlaylistAdapter(Context context, List playlists, ImageLoader imageLoader, boolean largeCell, OnItemClickedListener listener) { + super(context, playlists); + this.imageLoader = imageLoader; + this.largeCell = largeCell; + this.onItemClickedListener = listener; + } + public PlaylistAdapter(Context context, List headers, List> sections, ImageLoader imageLoader, boolean largeCell, OnItemClickedListener listener) { + super(context, headers, sections); + this.imageLoader = imageLoader; + this.largeCell = largeCell; + this.onItemClickedListener = listener; + } - @Override - public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - return new UpdateView.UpdateViewHolder(new PlaylistView(context, imageLoader, largeCell)); - } + @Override + public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + return new UpdateView.UpdateViewHolder(new PlaylistView(context, imageLoader, largeCell)); + } - @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Playlist playlist, int viewType) { - holder.getUpdateView().setObject(playlist); - holder.setItem(playlist); - } + @Override + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Playlist playlist, int viewType) { + holder.getUpdateView().setObject(playlist); + holder.setItem(playlist); + } - @Override - public int getItemViewType(Playlist playlist) { - return VIEW_TYPE_PLAYLIST; - } + @Override + public int getItemViewType(Playlist playlist) { + return VIEW_TYPE_PLAYLIST; + } - @Override - public String getTextToShowInBubble(int position) { - Object item = getItemForPosition(position); - if(item instanceof Playlist) { - return getNameIndex(((Playlist) item).getName()); - } else { - return null; - } - } + @Override + public String getTextToShowInBubble(int position) { + Object item = getItemForPosition(position); + if(item instanceof Playlist) { + return getNameIndex(((Playlist) item).getName()); + } else { + return null; + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/SearchAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/SearchAdapter.java index d5858c0..b76ffa2 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/SearchAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/SearchAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -45,96 +45,96 @@ import static net.nullsum.audinaut.adapter.EntryGridAdapter.VIEW_TYPE_ALBUM_LINE import static net.nullsum.audinaut.adapter.EntryGridAdapter.VIEW_TYPE_SONG; public class SearchAdapter extends ExpandableSectionAdapter { - private ImageLoader imageLoader; - private boolean largeAlbums; + private ImageLoader imageLoader; + private boolean largeAlbums; - private static final int MAX_ARTISTS = 10; - private static final int MAX_ALBUMS = 4; - private static final int MAX_SONGS = 10; + private static final int MAX_ARTISTS = 10; + private static final int MAX_ALBUMS = 4; + private static final int MAX_SONGS = 10; - public SearchAdapter(Context context, SearchResult searchResult, ImageLoader imageLoader, boolean largeAlbums, OnItemClickedListener listener) { - this.imageLoader = imageLoader; - this.largeAlbums = largeAlbums; + public SearchAdapter(Context context, SearchResult searchResult, ImageLoader imageLoader, boolean largeAlbums, OnItemClickedListener listener) { + this.imageLoader = imageLoader; + this.largeAlbums = largeAlbums; - List> sections = new ArrayList<>(); - List headers = new ArrayList<>(); - List defaultVisible = new ArrayList<>(); - Resources res = context.getResources(); - if(!searchResult.getArtists().isEmpty()) { - sections.add((List) (List) searchResult.getArtists()); - headers.add(res.getString(R.string.search_artists)); - defaultVisible.add(MAX_ARTISTS); - } - if(!searchResult.getAlbums().isEmpty()) { - sections.add((List) (List) searchResult.getAlbums()); - headers.add(res.getString(R.string.search_albums)); - defaultVisible.add(MAX_ALBUMS); - } - if(!searchResult.getSongs().isEmpty()) { - sections.add((List) (List) searchResult.getSongs()); - headers.add(res.getString(R.string.search_songs)); - defaultVisible.add(MAX_SONGS); - } - init(context, headers, sections, defaultVisible); + List> sections = new ArrayList<>(); + List headers = new ArrayList<>(); + List defaultVisible = new ArrayList<>(); + Resources res = context.getResources(); + if(!searchResult.getArtists().isEmpty()) { + sections.add((List) (List) searchResult.getArtists()); + headers.add(res.getString(R.string.search_artists)); + defaultVisible.add(MAX_ARTISTS); + } + if(!searchResult.getAlbums().isEmpty()) { + sections.add((List) (List) searchResult.getAlbums()); + headers.add(res.getString(R.string.search_albums)); + defaultVisible.add(MAX_ALBUMS); + } + if(!searchResult.getSongs().isEmpty()) { + sections.add((List) (List) searchResult.getSongs()); + headers.add(res.getString(R.string.search_songs)); + defaultVisible.add(MAX_SONGS); + } + init(context, headers, sections, defaultVisible); - this.onItemClickedListener = listener; - checkable = true; - } + this.onItemClickedListener = listener; + checkable = true; + } - @Override - public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - UpdateView updateView = null; - if(viewType == VIEW_TYPE_ALBUM_CELL || viewType == VIEW_TYPE_ALBUM_LINE) { - updateView = new AlbumView(context, viewType == VIEW_TYPE_ALBUM_CELL); - } else if(viewType == VIEW_TYPE_SONG) { - updateView = new SongView(context); - } else if(viewType == VIEW_TYPE_ARTIST) { - updateView = new ArtistView(context); - } + @Override + public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + UpdateView updateView = null; + if(viewType == VIEW_TYPE_ALBUM_CELL || viewType == VIEW_TYPE_ALBUM_LINE) { + updateView = new AlbumView(context, viewType == VIEW_TYPE_ALBUM_CELL); + } else if(viewType == VIEW_TYPE_SONG) { + updateView = new SongView(context); + } else if(viewType == VIEW_TYPE_ARTIST) { + updateView = new ArtistView(context); + } - return new UpdateView.UpdateViewHolder(updateView); - } + return new UpdateView.UpdateViewHolder(updateView); + } - @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Serializable item, int viewType) { - UpdateView view = holder.getUpdateView(); - if(viewType == VIEW_TYPE_ALBUM_CELL || viewType == VIEW_TYPE_ALBUM_LINE) { - AlbumView albumView = (AlbumView) view; - albumView.setObject((Entry) item, imageLoader); - } else if(viewType == VIEW_TYPE_SONG) { - SongView songView = (SongView) view; - songView.setObject((Entry) item, true); - } else if(viewType == VIEW_TYPE_ARTIST) { - view.setObject(item); - } - } + @Override + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Serializable item, int viewType) { + UpdateView view = holder.getUpdateView(); + if(viewType == VIEW_TYPE_ALBUM_CELL || viewType == VIEW_TYPE_ALBUM_LINE) { + AlbumView albumView = (AlbumView) view; + albumView.setObject((Entry) item, imageLoader); + } else if(viewType == VIEW_TYPE_SONG) { + SongView songView = (SongView) view; + songView.setObject((Entry) item, true); + } else if(viewType == VIEW_TYPE_ARTIST) { + view.setObject(item); + } + } - @Override - public int getItemViewType(Serializable item) { - if(item instanceof Entry) { - Entry entry = (Entry) item; - if (entry.isDirectory()) { - if (largeAlbums) { - return VIEW_TYPE_ALBUM_CELL; - } else { - return VIEW_TYPE_ALBUM_LINE; - } - } else { - return VIEW_TYPE_SONG; - } - } else { - return VIEW_TYPE_ARTIST; - } - } + @Override + public int getItemViewType(Serializable item) { + if(item instanceof Entry) { + Entry entry = (Entry) item; + if (entry.isDirectory()) { + if (largeAlbums) { + return VIEW_TYPE_ALBUM_CELL; + } else { + return VIEW_TYPE_ALBUM_LINE; + } + } else { + return VIEW_TYPE_SONG; + } + } else { + return VIEW_TYPE_ARTIST; + } + } - @Override - public void onCreateActionModeMenu(Menu menu, MenuInflater menuInflater) { - if(Util.isOffline(context)) { - menuInflater.inflate(R.menu.multiselect_media_offline, menu); - } else { - menuInflater.inflate(R.menu.multiselect_media, menu); - } + @Override + public void onCreateActionModeMenu(Menu menu, MenuInflater menuInflater) { + if(Util.isOffline(context)) { + menuInflater.inflate(R.menu.multiselect_media_offline, menu); + } else { + menuInflater.inflate(R.menu.multiselect_media, menu); + } - menu.removeItem(R.id.menu_remove_playlist); - } + menu.removeItem(R.id.menu_remove_playlist); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/SectionAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/SectionAdapter.java index 2a99425..1a310b1 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/SectionAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/SectionAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -46,471 +46,471 @@ import net.nullsum.audinaut.view.UpdateView; import net.nullsum.audinaut.view.UpdateView.UpdateViewHolder; public abstract class SectionAdapter extends RecyclerView.Adapter> { - private static String TAG = SectionAdapter.class.getSimpleName(); - public static int VIEW_TYPE_HEADER = 0; - public static String[] ignoredArticles; + private static String TAG = SectionAdapter.class.getSimpleName(); + public static int VIEW_TYPE_HEADER = 0; + public static String[] ignoredArticles; - protected Context context; - protected List headers; - protected List> sections; - protected boolean singleSectionHeader; - protected OnItemClickedListener onItemClickedListener; - protected List selected = new ArrayList<>(); - protected List selectedViews = new ArrayList<>(); - protected ActionMode currentActionMode; - protected boolean checkable = false; + protected Context context; + protected List headers; + protected List> sections; + protected boolean singleSectionHeader; + protected OnItemClickedListener onItemClickedListener; + protected List selected = new ArrayList<>(); + protected List selectedViews = new ArrayList<>(); + protected ActionMode currentActionMode; + protected boolean checkable = false; - protected SectionAdapter() {} - public SectionAdapter(Context context, List section) { - this(context, section, false); - } - public SectionAdapter(Context context, List section, boolean singleSectionHeader) { - this.context = context; - this.headers = Arrays.asList("Section"); - this.sections = new ArrayList<>(); - this.sections.add(section); - this.singleSectionHeader = singleSectionHeader; - } - public SectionAdapter(Context context, List headers, List> sections) { - this(context, headers, sections, true); - } - public SectionAdapter(Context context, List headers, List> sections, boolean singleSectionHeader){ - this.context = context; - this.headers = headers; - this.sections = sections; - this.singleSectionHeader = singleSectionHeader; - } + protected SectionAdapter() {} + public SectionAdapter(Context context, List section) { + this(context, section, false); + } + public SectionAdapter(Context context, List section, boolean singleSectionHeader) { + this.context = context; + this.headers = Arrays.asList("Section"); + this.sections = new ArrayList<>(); + this.sections.add(section); + this.singleSectionHeader = singleSectionHeader; + } + public SectionAdapter(Context context, List headers, List> sections) { + this(context, headers, sections, true); + } + public SectionAdapter(Context context, List headers, List> sections, boolean singleSectionHeader){ + this.context = context; + this.headers = headers; + this.sections = sections; + this.singleSectionHeader = singleSectionHeader; + } - public void replaceExistingData(List section) { - this.sections = new ArrayList<>(); - this.sections.add(section); - notifyDataSetChanged(); - } - public void replaceExistingData(List headers, List> sections) { - this.headers = headers; - this.sections = sections; - notifyDataSetChanged(); - } + public void replaceExistingData(List section) { + this.sections = new ArrayList<>(); + this.sections.add(section); + notifyDataSetChanged(); + } + public void replaceExistingData(List headers, List> sections) { + this.headers = headers; + this.sections = sections; + notifyDataSetChanged(); + } - @Override - public UpdateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - if(viewType == VIEW_TYPE_HEADER) { - return onCreateHeaderHolder(parent); - } else { - final UpdateViewHolder holder = onCreateSectionViewHolder(parent, viewType); - final UpdateView updateView = holder.getUpdateView(); + @Override + public UpdateViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + if(viewType == VIEW_TYPE_HEADER) { + return onCreateHeaderHolder(parent); + } else { + final UpdateViewHolder holder = onCreateSectionViewHolder(parent, viewType); + final UpdateView updateView = holder.getUpdateView(); - if(updateView != null) { - updateView.getChildAt(0).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - T item = holder.getItem(); - updateView.onClick(); - if (currentActionMode != null) { - if(updateView.isCheckable()) { - if (selected.contains(item)) { - selected.remove(item); - selectedViews.remove(updateView); - setChecked(updateView, false); - } else { - selected.add(item); - selectedViews.add(updateView); - setChecked(updateView, true); - } + if(updateView != null) { + updateView.getChildAt(0).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + T item = holder.getItem(); + updateView.onClick(); + if (currentActionMode != null) { + if(updateView.isCheckable()) { + if (selected.contains(item)) { + selected.remove(item); + selectedViews.remove(updateView); + setChecked(updateView, false); + } else { + selected.add(item); + selectedViews.add(updateView); + setChecked(updateView, true); + } - if (selected.isEmpty()) { - currentActionMode.finish(); - } else { - currentActionMode.setTitle(context.getResources().getString(R.string.select_album_n_selected, selected.size())); - } - } - } else if (onItemClickedListener != null) { - onItemClickedListener.onItemClicked(updateView, item); - } - } - }); + if (selected.isEmpty()) { + currentActionMode.finish(); + } else { + currentActionMode.setTitle(context.getResources().getString(R.string.select_album_n_selected, selected.size())); + } + } + } else if (onItemClickedListener != null) { + onItemClickedListener.onItemClicked(updateView, item); + } + } + }); - View moreButton = updateView.findViewById(R.id.item_more); - if (moreButton != null) { - moreButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - try { - final T item = holder.getItem(); - if (onItemClickedListener != null) { - PopupMenu popup = new PopupMenu(context, v); - onItemClickedListener.onCreateContextMenu(popup.getMenu(), popup.getMenuInflater(), updateView, item); + View moreButton = updateView.findViewById(R.id.item_more); + if (moreButton != null) { + moreButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + try { + final T item = holder.getItem(); + if (onItemClickedListener != null) { + PopupMenu popup = new PopupMenu(context, v); + onItemClickedListener.onCreateContextMenu(popup.getMenu(), popup.getMenuInflater(), updateView, item); - popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem menuItem) { - return onItemClickedListener.onContextItemSelected(menuItem, updateView, item); - } - }); - popup.show(); - } - } catch(Exception e) { - Log.w(TAG, "Failed to show popup", e); - } - } - }); + popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem menuItem) { + return onItemClickedListener.onContextItemSelected(menuItem, updateView, item); + } + }); + popup.show(); + } + } catch(Exception e) { + Log.w(TAG, "Failed to show popup", e); + } + } + }); - if(checkable) { - updateView.getChildAt(0).setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View v) { - if(updateView.isCheckable()) { - if (currentActionMode == null) { - startActionMode(holder); - } else { - updateView.getChildAt(0).performClick(); - } - } - return true; - } - }); - } - } - } + if(checkable) { + updateView.getChildAt(0).setOnLongClickListener(new View.OnLongClickListener() { + @Override + public boolean onLongClick(View v) { + if(updateView.isCheckable()) { + if (currentActionMode == null) { + startActionMode(holder); + } else { + updateView.getChildAt(0).performClick(); + } + } + return true; + } + }); + } + } + } - return holder; - } - } + return holder; + } + } - @Override - public void onBindViewHolder(UpdateViewHolder holder, int position) { - UpdateView updateView = holder.getUpdateView(); + @Override + public void onBindViewHolder(UpdateViewHolder holder, int position) { + UpdateView updateView = holder.getUpdateView(); - if(sections.size() == 1 && !singleSectionHeader) { - T item = sections.get(0).get(position); - onBindViewHolder(holder, item, getItemViewType(position)); - postBindView(updateView, item); - holder.setItem(item); - return; - } + if(sections.size() == 1 && !singleSectionHeader) { + T item = sections.get(0).get(position); + onBindViewHolder(holder, item, getItemViewType(position)); + postBindView(updateView, item); + holder.setItem(item); + return; + } - int subPosition = 0; - int subHeader = 0; - for(List section: sections) { - boolean validHeader = headers.get(subHeader) != null; - if(position == subPosition && validHeader) { - onBindHeaderHolder(holder, headers.get(subHeader), subHeader); - return; - } + int subPosition = 0; + int subHeader = 0; + for(List section: sections) { + boolean validHeader = headers.get(subHeader) != null; + if(position == subPosition && validHeader) { + onBindHeaderHolder(holder, headers.get(subHeader), subHeader); + return; + } - int headerOffset = validHeader ? 1 : 0; - if(position < (subPosition + section.size() + headerOffset)) { - T item = section.get(position - subPosition - headerOffset); - onBindViewHolder(holder, item, getItemViewType(item)); + int headerOffset = validHeader ? 1 : 0; + if(position < (subPosition + section.size() + headerOffset)) { + T item = section.get(position - subPosition - headerOffset); + onBindViewHolder(holder, item, getItemViewType(item)); - postBindView(updateView, item); - holder.setItem(item); - return; - } + postBindView(updateView, item); + holder.setItem(item); + return; + } - subPosition += section.size(); - if(validHeader) { - subPosition += 1; - } - subHeader++; - } - } + subPosition += section.size(); + if(validHeader) { + subPosition += 1; + } + subHeader++; + } + } - private void postBindView(UpdateView updateView, T item) { - if(updateView.isCheckable()) { - setChecked(updateView, selected.contains(item)); - } + private void postBindView(UpdateView updateView, T item) { + if(updateView.isCheckable()) { + setChecked(updateView, selected.contains(item)); + } - View moreButton = updateView.findViewById(R.id.item_more); - if(moreButton != null) { - if(onItemClickedListener != null) { - PopupMenu popup = new PopupMenu(context, moreButton); - Menu menu = popup.getMenu(); - onItemClickedListener.onCreateContextMenu(popup.getMenu(), popup.getMenuInflater(), updateView, item); - if (menu.size() == 0) { - moreButton.setVisibility(View.GONE); - } else { - moreButton.setVisibility(View.VISIBLE); - } - } else { - moreButton.setVisibility(View.VISIBLE); - } - } - } + View moreButton = updateView.findViewById(R.id.item_more); + if(moreButton != null) { + if(onItemClickedListener != null) { + PopupMenu popup = new PopupMenu(context, moreButton); + Menu menu = popup.getMenu(); + onItemClickedListener.onCreateContextMenu(popup.getMenu(), popup.getMenuInflater(), updateView, item); + if (menu.size() == 0) { + moreButton.setVisibility(View.GONE); + } else { + moreButton.setVisibility(View.VISIBLE); + } + } else { + moreButton.setVisibility(View.VISIBLE); + } + } + } - @Override - public int getItemCount() { - if(sections.size() == 1 && !singleSectionHeader) { - return sections.get(0).size(); - } + @Override + public int getItemCount() { + if(sections.size() == 1 && !singleSectionHeader) { + return sections.get(0).size(); + } - int count = 0; - for(String header: headers) { - if(header != null) { - count++; - } - } - for(List section: sections) { - count += section.size(); - } + int count = 0; + for(String header: headers) { + if(header != null) { + count++; + } + } + for(List section: sections) { + count += section.size(); + } - return count; - } + return count; + } - @Override - public int getItemViewType(int position) { - if(sections.size() == 1 && !singleSectionHeader) { - return getItemViewType(sections.get(0).get(position)); - } + @Override + public int getItemViewType(int position) { + if(sections.size() == 1 && !singleSectionHeader) { + return getItemViewType(sections.get(0).get(position)); + } - int subPosition = 0; - int subHeader = 0; - for(List section: sections) { - boolean validHeader = headers.get(subHeader) != null; - if(position == subPosition && validHeader) { - return VIEW_TYPE_HEADER; - } + int subPosition = 0; + int subHeader = 0; + for(List section: sections) { + boolean validHeader = headers.get(subHeader) != null; + if(position == subPosition && validHeader) { + return VIEW_TYPE_HEADER; + } - int headerOffset = validHeader ? 1 : 0; - if(position < (subPosition + section.size() + headerOffset)) { - return getItemViewType(section.get(position - subPosition - headerOffset)); - } + int headerOffset = validHeader ? 1 : 0; + if(position < (subPosition + section.size() + headerOffset)) { + return getItemViewType(section.get(position - subPosition - headerOffset)); + } - subPosition += section.size(); - if(validHeader) { - subPosition += 1; - } - subHeader++; - } + subPosition += section.size(); + if(validHeader) { + subPosition += 1; + } + subHeader++; + } - return -1; - } + return -1; + } - public UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { - return new UpdateViewHolder(new BasicHeaderView(context)); - } - public void onBindHeaderHolder(UpdateViewHolder holder, String header, int sectionIndex) { - UpdateView view = holder.getUpdateView(); - if(view != null) { - view.setObject(header); - } - } + public UpdateViewHolder onCreateHeaderHolder(ViewGroup parent) { + return new UpdateViewHolder(new BasicHeaderView(context)); + } + public void onBindHeaderHolder(UpdateViewHolder holder, String header, int sectionIndex) { + UpdateView view = holder.getUpdateView(); + if(view != null) { + view.setObject(header); + } + } - public T getItemForPosition(int position) { - if(sections.size() == 1 && !singleSectionHeader) { - return sections.get(0).get(position); - } + public T getItemForPosition(int position) { + if(sections.size() == 1 && !singleSectionHeader) { + return sections.get(0).get(position); + } - int subPosition = 0; - for(List section: sections) { - if(position == subPosition) { - return null; - } + int subPosition = 0; + for(List section: sections) { + if(position == subPosition) { + return null; + } - if(position <= (subPosition + section.size())) { - return section.get(position - subPosition - 1); - } + if(position <= (subPosition + section.size())) { + return section.get(position - subPosition - 1); + } - subPosition += section.size() + 1; - } + subPosition += section.size() + 1; + } - return null; - } - public int getItemPosition(T item) { - if(sections.size() == 1 && !singleSectionHeader) { - return sections.get(0).indexOf(item); - } + return null; + } + public int getItemPosition(T item) { + if(sections.size() == 1 && !singleSectionHeader) { + return sections.get(0).indexOf(item); + } - int subPosition = 0; - for(List section: sections) { - subPosition += section.size() + 1; + int subPosition = 0; + for(List section: sections) { + subPosition += section.size() + 1; - int position = section.indexOf(item); - if(position != -1) { - return position + subPosition; - } - } + int position = section.indexOf(item); + if(position != -1) { + return position + subPosition; + } + } - return -1; - } + return -1; + } - public void setOnItemClickedListener(OnItemClickedListener onItemClickedListener) { - this.onItemClickedListener = onItemClickedListener; - } + public void setOnItemClickedListener(OnItemClickedListener onItemClickedListener) { + this.onItemClickedListener = onItemClickedListener; + } - public void addSelected(T item) { - selected.add(item); - } - public List getSelected() { - List selected = new ArrayList<>(); - selected.addAll(this.selected); - return selected; - } + public void addSelected(T item) { + selected.add(item); + } + public List getSelected() { + List selected = new ArrayList<>(); + selected.addAll(this.selected); + return selected; + } - public void clearSelected() { - // TODO: This needs to work with multiple sections - for(T item: selected) { - int index = sections.get(0).indexOf(item); + public void clearSelected() { + // TODO: This needs to work with multiple sections + for(T item: selected) { + int index = sections.get(0).indexOf(item); - if(singleSectionHeader) { - index++; - } - } - selected.clear(); + if(singleSectionHeader) { + index++; + } + } + selected.clear(); - for(UpdateView updateView: selectedViews) { - updateView.setChecked(false); - } - } + for(UpdateView updateView: selectedViews) { + updateView.setChecked(false); + } + } - public void moveItem(int from, int to) { - List section = sections.get(0); - int max = section.size(); - if(to >= max) { - to = max - 1; - } else if(to < 0) { - to = 0; - } + public void moveItem(int from, int to) { + List section = sections.get(0); + int max = section.size(); + if(to >= max) { + to = max - 1; + } else if(to < 0) { + to = 0; + } - T moved = section.remove(from); - section.add(to, moved); + T moved = section.remove(from); + section.add(to, moved); - notifyItemMoved(from, to); - } - public void removeItem(T item) { - int subPosition = 0; - for(List section: sections) { - if(sections.size() > 1 || singleSectionHeader) { - subPosition++; - } + notifyItemMoved(from, to); + } + public void removeItem(T item) { + int subPosition = 0; + for(List section: sections) { + if(sections.size() > 1 || singleSectionHeader) { + subPosition++; + } - int index = section.indexOf(item); - if (index != -1) { - section.remove(item); - notifyItemRemoved(subPosition + index); - break; - } + int index = section.indexOf(item); + if (index != -1) { + section.remove(item); + notifyItemRemoved(subPosition + index); + break; + } - subPosition += section.size(); - } - } + subPosition += section.size(); + } + } - public abstract UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType); - public abstract void onBindViewHolder(UpdateViewHolder holder, T item, int viewType); - public abstract int getItemViewType(T item); - public void setCheckable(boolean checkable) { - this.checkable = checkable; - } - public void setChecked(UpdateView updateView, boolean checked) { - updateView.setChecked(checked); - } - public void onCreateActionModeMenu(Menu menu, MenuInflater menuInflater) {} + public abstract UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType); + public abstract void onBindViewHolder(UpdateViewHolder holder, T item, int viewType); + public abstract int getItemViewType(T item); + public void setCheckable(boolean checkable) { + this.checkable = checkable; + } + public void setChecked(UpdateView updateView, boolean checked) { + updateView.setChecked(checked); + } + public void onCreateActionModeMenu(Menu menu, MenuInflater menuInflater) {} - private void startActionMode(final UpdateView.UpdateViewHolder holder) { - final UpdateView updateView = holder.getUpdateView(); - if (context instanceof SubsonicFragmentActivity && currentActionMode == null) { - final SubsonicFragmentActivity fragmentActivity = (SubsonicFragmentActivity) context; - fragmentActivity.startSupportActionMode(new ActionMode.Callback() { - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - currentActionMode = mode; + private void startActionMode(final UpdateView.UpdateViewHolder holder) { + final UpdateView updateView = holder.getUpdateView(); + if (context instanceof SubsonicFragmentActivity && currentActionMode == null) { + final SubsonicFragmentActivity fragmentActivity = (SubsonicFragmentActivity) context; + fragmentActivity.startSupportActionMode(new ActionMode.Callback() { + @Override + public boolean onCreateActionMode(ActionMode mode, Menu menu) { + currentActionMode = mode; - T item = holder.getItem(); - selected.add(item); - selectedViews.add(updateView); - setChecked(updateView, true); + T item = holder.getItem(); + selected.add(item); + selectedViews.add(updateView); + setChecked(updateView, true); - onCreateActionModeMenu(menu, mode.getMenuInflater()); - MenuUtil.hideMenuItems(context, menu, updateView); + onCreateActionModeMenu(menu, mode.getMenuInflater()); + MenuUtil.hideMenuItems(context, menu, updateView); - mode.setTitle(context.getResources().getString(R.string.select_album_n_selected, selected.size())); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true)) { - TypedValue typedValue = new TypedValue(); - Resources.Theme theme = context.getTheme(); - theme.resolveAttribute(R.attr.colorPrimaryDark, typedValue, true); - int colorPrimaryDark = typedValue.data; + mode.setTitle(context.getResources().getString(R.string.select_album_n_selected, selected.size())); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true)) { + TypedValue typedValue = new TypedValue(); + Resources.Theme theme = context.getTheme(); + theme.resolveAttribute(R.attr.colorPrimaryDark, typedValue, true); + int colorPrimaryDark = typedValue.data; - Window window = ((SubsonicFragmentActivity) context).getWindow(); - window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); - window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - window.setStatusBarColor(colorPrimaryDark); - } - return true; - } + Window window = ((SubsonicFragmentActivity) context).getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); + window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + window.setStatusBarColor(colorPrimaryDark); + } + return true; + } - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - return false; - } + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + return false; + } - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - if (fragmentActivity.onOptionsItemSelected(item)) { - currentActionMode.finish(); - return true; - } else { - return false; - } - } + @Override + public boolean onActionItemClicked(ActionMode mode, MenuItem item) { + if (fragmentActivity.onOptionsItemSelected(item)) { + currentActionMode.finish(); + return true; + } else { + return false; + } + } - @Override - public void onDestroyActionMode(ActionMode mode) { - currentActionMode = null; - selected.clear(); - for (UpdateView updateView : selectedViews) { - updateView.setChecked(false); - } - selectedViews.clear(); + @Override + public void onDestroyActionMode(ActionMode mode) { + currentActionMode = null; + selected.clear(); + for (UpdateView updateView : selectedViews) { + updateView.setChecked(false); + } + selectedViews.clear(); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true)) { - Window window = ((SubsonicFragmentActivity) context).getWindow(); - window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - } - } - }); - } - } - public void stopActionMode() { - if(currentActionMode != null) { - currentActionMode.finish(); - } - } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true)) { + Window window = ((SubsonicFragmentActivity) context).getWindow(); + window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); + } + } + }); + } + } + public void stopActionMode() { + if(currentActionMode != null) { + currentActionMode.finish(); + } + } - public String getNameIndex(String name) { - return getNameIndex(name, false); - } - public String getNameIndex(String name, boolean removeIgnoredArticles) { - if(name == null) { - return "*"; - } + public String getNameIndex(String name) { + return getNameIndex(name, false); + } + public String getNameIndex(String name, boolean removeIgnoredArticles) { + if(name == null) { + return "*"; + } - if(removeIgnoredArticles) { - if (ignoredArticles == null) { - SharedPreferences prefs = Util.getPreferences(context); - String ignoredArticlesString = prefs.getString(Constants.CACHE_KEY_IGNORE, "The El La Los Las Le Les"); - ignoredArticles = ignoredArticlesString.split(" "); - } + if(removeIgnoredArticles) { + if (ignoredArticles == null) { + SharedPreferences prefs = Util.getPreferences(context); + String ignoredArticlesString = prefs.getString(Constants.CACHE_KEY_IGNORE, "The El La Los Las Le Les"); + ignoredArticles = ignoredArticlesString.split(" "); + } - name = name.toLowerCase(); - for (String article : ignoredArticles) { - int index = name.indexOf(article.toLowerCase() + " "); - if (index == 0) { - name = name.substring(article.length() + 1); - } - } - } + name = name.toLowerCase(); + for (String article : ignoredArticles) { + int index = name.indexOf(article.toLowerCase() + " "); + if (index == 0) { + name = name.substring(article.length() + 1); + } + } + } - String index = name.substring(0, 1).toUpperCase(); - if (!Character.isLetter(index.charAt(0))) { - index = "#"; - } + String index = name.substring(0, 1).toUpperCase(); + if (!Character.isLetter(index.charAt(0))) { + index = "#"; + } - return index; - } + return index; + } - public interface OnItemClickedListener { - void onItemClicked(UpdateView updateView, T item); - void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, T item); - boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, T item); - } + public interface OnItemClickedListener { + void onItemClicked(UpdateView updateView, T item); + void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, T item); + boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, T item); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/adapter/SettingsAdapter.java b/app/src/main/java/net/nullsum/audinaut/adapter/SettingsAdapter.java index 5d0764e..4cf06cf 100644 --- a/app/src/main/java/net/nullsum/audinaut/adapter/SettingsAdapter.java +++ b/app/src/main/java/net/nullsum/audinaut/adapter/SettingsAdapter.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.adapter; @@ -36,86 +36,86 @@ import net.nullsum.audinaut.view.UpdateView; import static net.nullsum.audinaut.domain.User.Setting; public class SettingsAdapter extends SectionAdapter { - private static final String TAG = SettingsAdapter.class.getSimpleName(); - public final int VIEW_TYPE_SETTING = 1; - public final int VIEW_TYPE_SETTING_HEADER = 2; + private static final String TAG = SettingsAdapter.class.getSimpleName(); + public final int VIEW_TYPE_SETTING = 1; + public final int VIEW_TYPE_SETTING_HEADER = 2; - private final User user; - private final boolean editable; - private final ImageLoader imageLoader; + private final User user; + private final boolean editable; + private final ImageLoader imageLoader; - public SettingsAdapter(Context context, User user, List headers, List> settingSections, ImageLoader imageLoader, boolean editable, OnItemClickedListener onItemClickedListener) { - super(context, headers, settingSections, imageLoader != null); - this.user = user; - this.imageLoader = imageLoader; - this.editable = editable; - this.onItemClickedListener = onItemClickedListener; + public SettingsAdapter(Context context, User user, List headers, List> settingSections, ImageLoader imageLoader, boolean editable, OnItemClickedListener onItemClickedListener) { + super(context, headers, settingSections, imageLoader != null); + this.user = user; + this.imageLoader = imageLoader; + this.editable = editable; + this.onItemClickedListener = onItemClickedListener; - for(List settings: sections) { - for (Setting setting : settings) { - if (setting.getValue()) { - addSelected(setting); - } - } - } - } + for(List settings: sections) { + for (Setting setting : settings) { + if (setting.getValue()) { + addSelected(setting); + } + } + } + } - @Override - public int getItemViewType(int position) { - int viewType = super.getItemViewType(position); - if(viewType == SectionAdapter.VIEW_TYPE_HEADER) { - if(position == 0 && imageLoader != null) { - return VIEW_TYPE_HEADER; - } else { - return VIEW_TYPE_SETTING_HEADER; - } - } else { - return viewType; - } - } + @Override + public int getItemViewType(int position) { + int viewType = super.getItemViewType(position); + if(viewType == SectionAdapter.VIEW_TYPE_HEADER) { + if(position == 0 && imageLoader != null) { + return VIEW_TYPE_HEADER; + } else { + return VIEW_TYPE_SETTING_HEADER; + } + } else { + return viewType; + } + } - public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String description, int sectionIndex) { - View header = holder.getView(); - } + public void onBindHeaderHolder(UpdateView.UpdateViewHolder holder, String description, int sectionIndex) { + View header = holder.getView(); + } - @Override - public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { - if(viewType == VIEW_TYPE_SETTING_HEADER) { - return new UpdateView.UpdateViewHolder(new BasicHeaderView(context)); - } else { - return new UpdateView.UpdateViewHolder(new SettingView(context)); - } - } + @Override + public UpdateView.UpdateViewHolder onCreateSectionViewHolder(ViewGroup parent, int viewType) { + if(viewType == VIEW_TYPE_SETTING_HEADER) { + return new UpdateView.UpdateViewHolder(new BasicHeaderView(context)); + } else { + return new UpdateView.UpdateViewHolder(new SettingView(context)); + } + } - @Override - public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Setting item, int viewType) { - holder.getUpdateView().setObject(item, editable); - } + @Override + public void onBindViewHolder(UpdateView.UpdateViewHolder holder, Setting item, int viewType) { + holder.getUpdateView().setObject(item, editable); + } - @Override - public int getItemViewType(Setting item) { - return VIEW_TYPE_SETTING; - } + @Override + public int getItemViewType(Setting item) { + return VIEW_TYPE_SETTING; + } - @Override - public void setChecked(UpdateView updateView, boolean checked) { - if(updateView instanceof SettingView) { - updateView.setChecked(checked); - } - } + @Override + public void setChecked(UpdateView updateView, boolean checked) { + if(updateView instanceof SettingView) { + updateView.setChecked(checked); + } + } - public static SettingsAdapter getSettingsAdapter(Context context, User user, ImageLoader imageLoader, OnItemClickedListener onItemClickedListener) { - return getSettingsAdapter(context, user, imageLoader, true, onItemClickedListener); - } - public static SettingsAdapter getSettingsAdapter(Context context, User user, ImageLoader imageLoader, boolean isEditable, OnItemClickedListener onItemClickedListener) { - List headers = new ArrayList<>(); - List> settingsSections = new ArrayList<>(); - settingsSections.add(user.getSettings()); + public static SettingsAdapter getSettingsAdapter(Context context, User user, ImageLoader imageLoader, OnItemClickedListener onItemClickedListener) { + return getSettingsAdapter(context, user, imageLoader, true, onItemClickedListener); + } + public static SettingsAdapter getSettingsAdapter(Context context, User user, ImageLoader imageLoader, boolean isEditable, OnItemClickedListener onItemClickedListener) { + List headers = new ArrayList<>(); + List> settingsSections = new ArrayList<>(); + settingsSections.add(user.getSettings()); - if(user.getMusicFolderSettings() != null) { - settingsSections.add(user.getMusicFolderSettings()); - } + if(user.getMusicFolderSettings() != null) { + settingsSections.add(user.getMusicFolderSettings()); + } - return new SettingsAdapter(context, user, headers, settingsSections, imageLoader, isEditable, onItemClickedListener); - } + return new SettingsAdapter(context, user, headers, settingsSections, imageLoader, isEditable, onItemClickedListener); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/audiofx/AudioEffectsController.java b/app/src/main/java/net/nullsum/audinaut/audiofx/AudioEffectsController.java index a63eed7..6549538 100644 --- a/app/src/main/java/net/nullsum/audinaut/audiofx/AudioEffectsController.java +++ b/app/src/main/java/net/nullsum/audinaut/audiofx/AudioEffectsController.java @@ -29,27 +29,27 @@ public class AudioEffectsController { private static final String TAG = AudioEffectsController.class.getSimpleName(); private final Context context; - private int audioSessionId = 0; + private int audioSessionId = 0; - private EqualizerController equalizerController; + private EqualizerController equalizerController; public AudioEffectsController(Context context, int audioSessionId) { this.context = context; - this.audioSessionId = audioSessionId; + this.audioSessionId = audioSessionId; } - public void release() { - if(equalizerController != null) { - equalizerController.release(); - } - } + public void release() { + if(equalizerController != null) { + equalizerController.release(); + } + } - public EqualizerController getEqualizerController() { - if (equalizerController == null) { - equalizerController = new EqualizerController(context, audioSessionId); + public EqualizerController getEqualizerController() { + if (equalizerController == null) { + equalizerController = new EqualizerController(context, audioSessionId); equalizerController.loadSettings(); - } - return equalizerController; - } + } + return equalizerController; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/audiofx/LoudnessEnhancerController.java b/app/src/main/java/net/nullsum/audinaut/audiofx/LoudnessEnhancerController.java index c0b299c..3e67334 100644 --- a/app/src/main/java/net/nullsum/audinaut/audiofx/LoudnessEnhancerController.java +++ b/app/src/main/java/net/nullsum/audinaut/audiofx/LoudnessEnhancerController.java @@ -1,20 +1,20 @@ /* - This file is part of Subsonic. + This file is part of Subsonic. - Subsonic 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. + Subsonic 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. - Subsonic 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. + Subsonic 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 Subsonic. If not, see . + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.audiofx; @@ -23,55 +23,55 @@ import android.media.audiofx.LoudnessEnhancer; import android.util.Log; public class LoudnessEnhancerController { - private static final String TAG = LoudnessEnhancerController.class.getSimpleName(); + private static final String TAG = LoudnessEnhancerController.class.getSimpleName(); - private final Context context; - private LoudnessEnhancer enhancer; - private boolean released = false; - private int audioSessionId = 0; + private final Context context; + private LoudnessEnhancer enhancer; + private boolean released = false; + private int audioSessionId = 0; - public LoudnessEnhancerController(Context context, int audioSessionId) { - this.context = context; - try { - this.audioSessionId = audioSessionId; - enhancer = new LoudnessEnhancer(audioSessionId); - } catch (Throwable x) { - Log.w(TAG, "Failed to create enhancer", x); - } - } + public LoudnessEnhancerController(Context context, int audioSessionId) { + this.context = context; + try { + this.audioSessionId = audioSessionId; + enhancer = new LoudnessEnhancer(audioSessionId); + } catch (Throwable x) { + Log.w(TAG, "Failed to create enhancer", x); + } + } - public boolean isAvailable() { - return enhancer != null; - } + public boolean isAvailable() { + return enhancer != null; + } - public boolean isEnabled() { - try { - return isAvailable() && enhancer.getEnabled(); - } catch(Exception e) { - return false; - } - } + public boolean isEnabled() { + try { + return isAvailable() && enhancer.getEnabled(); + } catch(Exception e) { + return false; + } + } - public void enable() { - enhancer.setEnabled(true); - } - public void disable() { - enhancer.setEnabled(false); - } + public void enable() { + enhancer.setEnabled(true); + } + public void disable() { + enhancer.setEnabled(false); + } - public float getGain() { - return enhancer.getTargetGain(); - } - public void setGain(int gain) { - enhancer.setTargetGain(gain); - } + public float getGain() { + return enhancer.getTargetGain(); + } + public void setGain(int gain) { + enhancer.setTargetGain(gain); + } - public void release() { - if (isAvailable()) { - enhancer.release(); - released = true; - } - } + public void release() { + if (isAvailable()) { + enhancer.release(); + released = true; + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/domain/MusicDirectory.java b/app/src/main/java/net/nullsum/audinaut/domain/MusicDirectory.java index acc4adc..61d9512 100644 --- a/app/src/main/java/net/nullsum/audinaut/domain/MusicDirectory.java +++ b/app/src/main/java/net/nullsum/audinaut/domain/MusicDirectory.java @@ -43,19 +43,19 @@ import net.nullsum.audinaut.util.Util; * @author Sindre Mehus */ public class MusicDirectory implements Serializable { - private static final String TAG = MusicDirectory.class.getSimpleName(); + private static final String TAG = MusicDirectory.class.getSimpleName(); private String name; - private String id; - private String parent; + private String id; + private String parent; private List children; - public MusicDirectory() { - children = new ArrayList(); - } - public MusicDirectory(List children) { - this.children = children; - } + public MusicDirectory() { + children = new ArrayList(); + } + public MusicDirectory(List children) { + this.children = children; + } public String getName() { return name; @@ -64,35 +64,35 @@ public class MusicDirectory implements Serializable { public void setName(String name) { this.name = name; } - - public String getId() { - return id; - } - public void setId(String id) { - this.id = id; - } - - public String getParent() { - return parent; - } + public String getId() { + return id; + } - public void setParent(String parent) { - this.parent = parent; - } + public void setId(String id) { + this.id = id; + } - public void addChild(Entry child) { - if(child != null) { - children.add(child); - } - } - public void addChildren(List children) { - this.children.addAll(children); - } - - public void replaceChildren(List children) { - this.children = children; - } + public String getParent() { + return parent; + } + + public void setParent(String parent) { + this.parent = parent; + } + + public void addChild(Entry child) { + if(child != null) { + children.add(child); + } + } + public void addChildren(List children) { + this.children.addAll(children); + } + + public void replaceChildren(List children) { + this.children = children; + } public synchronized List getChildren() { return getChildren(true, true); @@ -111,209 +111,209 @@ public class MusicDirectory implements Serializable { } return result; } - public synchronized List getSongs() { - List result = new ArrayList(); - for (Entry child : children) { - if (child != null && !child.isDirectory()) { - result.add(child); - } - } - return result; - } - - public synchronized int getChildrenSize() { - return children.size(); - } + public synchronized List getSongs() { + List result = new ArrayList(); + for (Entry child : children) { + if (child != null && !child.isDirectory()) { + result.add(child); + } + } + return result; + } - public void shuffleChildren() { - Collections.shuffle(this.children); - } - - public void sortChildren(Context context, int instance) { + public synchronized int getChildrenSize() { + return children.size(); + } + + public void shuffleChildren() { + Collections.shuffle(this.children); + } + + public void sortChildren(Context context, int instance) { sortChildren(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_CUSTOM_SORT_ENABLED, true)); - } - public void sortChildren(boolean byYear) { - EntryComparator.sort(children, byYear); - } + } + public void sortChildren(boolean byYear) { + EntryComparator.sort(children, byYear); + } - public synchronized boolean updateMetadata(MusicDirectory refreshedDirectory) { - boolean metadataUpdated = false; - Iterator it = children.iterator(); - while(it.hasNext()) { - Entry entry = it.next(); - int index = refreshedDirectory.children.indexOf(entry); - if(index != -1) { - final Entry refreshed = refreshedDirectory.children.get(index); + public synchronized boolean updateMetadata(MusicDirectory refreshedDirectory) { + boolean metadataUpdated = false; + Iterator it = children.iterator(); + while(it.hasNext()) { + Entry entry = it.next(); + int index = refreshedDirectory.children.indexOf(entry); + if(index != -1) { + final Entry refreshed = refreshedDirectory.children.get(index); - entry.setTitle(refreshed.getTitle()); - entry.setAlbum(refreshed.getAlbum()); - entry.setArtist(refreshed.getArtist()); - entry.setTrack(refreshed.getTrack()); - entry.setYear(refreshed.getYear()); - entry.setGenre(refreshed.getGenre()); - entry.setTranscodedContentType(refreshed.getTranscodedContentType()); - entry.setTranscodedSuffix(refreshed.getTranscodedSuffix()); - entry.setDiscNumber(refreshed.getDiscNumber()); - entry.setType(refreshed.getType()); - if(!Util.equals(entry.getCoverArt(), refreshed.getCoverArt())) { - metadataUpdated = true; - entry.setCoverArt(refreshed.getCoverArt()); - } + entry.setTitle(refreshed.getTitle()); + entry.setAlbum(refreshed.getAlbum()); + entry.setArtist(refreshed.getArtist()); + entry.setTrack(refreshed.getTrack()); + entry.setYear(refreshed.getYear()); + entry.setGenre(refreshed.getGenre()); + entry.setTranscodedContentType(refreshed.getTranscodedContentType()); + entry.setTranscodedSuffix(refreshed.getTranscodedSuffix()); + entry.setDiscNumber(refreshed.getDiscNumber()); + entry.setType(refreshed.getType()); + if(!Util.equals(entry.getCoverArt(), refreshed.getCoverArt())) { + metadataUpdated = true; + entry.setCoverArt(refreshed.getCoverArt()); + } - new UpdateHelper.EntryInstanceUpdater(entry) { - @Override - public void update(Entry found) { - found.setTitle(refreshed.getTitle()); - found.setAlbum(refreshed.getAlbum()); - found.setArtist(refreshed.getArtist()); - found.setTrack(refreshed.getTrack()); - found.setYear(refreshed.getYear()); - found.setGenre(refreshed.getGenre()); - found.setTranscodedContentType(refreshed.getTranscodedContentType()); - found.setTranscodedSuffix(refreshed.getTranscodedSuffix()); - found.setDiscNumber(refreshed.getDiscNumber()); - found.setType(refreshed.getType()); - if(!Util.equals(found.getCoverArt(), refreshed.getCoverArt())) { - found.setCoverArt(refreshed.getCoverArt()); - metadataUpdate = DownloadService.METADATA_UPDATED_COVER_ART; - } - } - }.execute(); - } - } + new UpdateHelper.EntryInstanceUpdater(entry) { + @Override + public void update(Entry found) { + found.setTitle(refreshed.getTitle()); + found.setAlbum(refreshed.getAlbum()); + found.setArtist(refreshed.getArtist()); + found.setTrack(refreshed.getTrack()); + found.setYear(refreshed.getYear()); + found.setGenre(refreshed.getGenre()); + found.setTranscodedContentType(refreshed.getTranscodedContentType()); + found.setTranscodedSuffix(refreshed.getTranscodedSuffix()); + found.setDiscNumber(refreshed.getDiscNumber()); + found.setType(refreshed.getType()); + if(!Util.equals(found.getCoverArt(), refreshed.getCoverArt())) { + found.setCoverArt(refreshed.getCoverArt()); + metadataUpdate = DownloadService.METADATA_UPDATED_COVER_ART; + } + } + }.execute(); + } + } - return metadataUpdated; - } - public synchronized boolean updateEntriesList(Context context, int instance, MusicDirectory refreshedDirectory) { - boolean changed = false; - Iterator it = children.iterator(); - while(it.hasNext()) { - Entry entry = it.next(); - // No longer exists in here - if(refreshedDirectory.children.indexOf(entry) == -1) { - it.remove(); - changed = true; - } - } + return metadataUpdated; + } + public synchronized boolean updateEntriesList(Context context, int instance, MusicDirectory refreshedDirectory) { + boolean changed = false; + Iterator it = children.iterator(); + while(it.hasNext()) { + Entry entry = it.next(); + // No longer exists in here + if(refreshedDirectory.children.indexOf(entry) == -1) { + it.remove(); + changed = true; + } + } - // Make sure we contain all children from refreshed set - boolean resort = false; - for(Entry refreshed: refreshedDirectory.children) { - if(!this.children.contains(refreshed)) { - this.children.add(refreshed); - resort = true; - changed = true; - } - } + // Make sure we contain all children from refreshed set + boolean resort = false; + for(Entry refreshed: refreshedDirectory.children) { + if(!this.children.contains(refreshed)) { + this.children.add(refreshed); + resort = true; + changed = true; + } + } - if(resort) { - this.sortChildren(context, instance); - } + if(resort) { + this.sortChildren(context, instance); + } - return changed; - } + return changed; + } public static class Entry implements Serializable { - public static final int TYPE_SONG = 0; + public static final int TYPE_SONG = 0; - private String id; - private String parent; - private String grandParent; - private String albumId; - private String artistId; - private boolean directory; - private String title; - private String album; - private String artist; - private Integer track; - private Integer year; - private String genre; - private String contentType; - private String suffix; - private String transcodedContentType; - private String transcodedSuffix; - private String coverArt; - private Long size; - private Integer duration; - private Integer bitRate; - private String path; - private Integer discNumber; - private int type = 0; - private int closeness; - private transient Artist linkedArtist; + private String id; + private String parent; + private String grandParent; + private String albumId; + private String artistId; + private boolean directory; + private String title; + private String album; + private String artist; + private Integer track; + private Integer year; + private String genre; + private String contentType; + private String suffix; + private String transcodedContentType; + private String transcodedSuffix; + private String coverArt; + private Long size; + private Integer duration; + private Integer bitRate; + private String path; + private Integer discNumber; + private int type = 0; + private int closeness; + private transient Artist linkedArtist; - public Entry() { + public Entry() { - } - public Entry(String id) { - this.id = id; - } - public Entry(Artist artist) { - this.id = artist.getId(); - this.title = artist.getName(); - this.directory = true; - this.linkedArtist = artist; - } - - public void loadMetadata(File file) { - try { - MediaMetadataRetriever metadata = new MediaMetadataRetriever(); - metadata.setDataSource(file.getAbsolutePath()); - String discNumber = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER); - if(discNumber == null) { - discNumber = "1/1"; - } - int slashIndex = discNumber.indexOf("/"); - if(slashIndex > 0) { - discNumber = discNumber.substring(0, slashIndex); - } - try { - setDiscNumber(Integer.parseInt(discNumber)); - } catch(Exception e) { - Log.w(TAG, "Non numbers in disc field!"); - } - String bitrate = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE); - setBitRate(Integer.parseInt((bitrate != null) ? bitrate : "0") / 1000); - String length = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); - setDuration(Integer.parseInt(length) / 1000); - String artist = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST); - if(artist != null) { - setArtist(artist); - } - String album = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM); - if(album != null) { - setAlbum(album); - } - metadata.release(); - } catch(Exception e) { - Log.i(TAG, "Device doesn't properly support MediaMetadataRetreiver", e); - } - } - public void rebaseTitleOffPath() { - try { - String filename = getPath(); - if(filename == null) { - return; - } + } + public Entry(String id) { + this.id = id; + } + public Entry(Artist artist) { + this.id = artist.getId(); + this.title = artist.getName(); + this.directory = true; + this.linkedArtist = artist; + } - int index = filename.lastIndexOf('/'); - if (index != -1) { - filename = filename.substring(index + 1); - if (getTrack() != null) { - filename = filename.replace(String.format("%02d ", getTrack()), ""); - } + public void loadMetadata(File file) { + try { + MediaMetadataRetriever metadata = new MediaMetadataRetriever(); + metadata.setDataSource(file.getAbsolutePath()); + String discNumber = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER); + if(discNumber == null) { + discNumber = "1/1"; + } + int slashIndex = discNumber.indexOf("/"); + if(slashIndex > 0) { + discNumber = discNumber.substring(0, slashIndex); + } + try { + setDiscNumber(Integer.parseInt(discNumber)); + } catch(Exception e) { + Log.w(TAG, "Non numbers in disc field!"); + } + String bitrate = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE); + setBitRate(Integer.parseInt((bitrate != null) ? bitrate : "0") / 1000); + String length = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); + setDuration(Integer.parseInt(length) / 1000); + String artist = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST); + if(artist != null) { + setArtist(artist); + } + String album = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ALBUM); + if(album != null) { + setAlbum(album); + } + metadata.release(); + } catch(Exception e) { + Log.i(TAG, "Device doesn't properly support MediaMetadataRetreiver", e); + } + } + public void rebaseTitleOffPath() { + try { + String filename = getPath(); + if(filename == null) { + return; + } - index = filename.lastIndexOf('.'); - if(index != -1) { - filename = filename.substring(0, index); - } + int index = filename.lastIndexOf('/'); + if (index != -1) { + filename = filename.substring(index + 1); + if (getTrack() != null) { + filename = filename.replace(String.format("%02d ", getTrack()), ""); + } - setTitle(filename); - } - } catch(Exception e) { - Log.w(TAG, "Failed to update title based off of path", e); - } - } + index = filename.lastIndexOf('.'); + if(index != -1) { + filename = filename.substring(0, index); + } + + setTitle(filename); + } + } catch(Exception e) { + Log.w(TAG, "Failed to update title based off of path", e); + } + } public String getId() { return id; @@ -330,8 +330,8 @@ public class MusicDirectory implements Serializable { public void setParent(String parent) { this.parent = parent; } - - public String getGrandParent() { + + public String getGrandParent() { return grandParent; } @@ -339,21 +339,21 @@ public class MusicDirectory implements Serializable { this.grandParent = grandParent; } - public String getAlbumId() { - return albumId; - } + public String getAlbumId() { + return albumId; + } - public void setAlbumId(String albumId) { - this.albumId = albumId; - } + public void setAlbumId(String albumId) { + this.albumId = albumId; + } - public String getArtistId() { - return artistId; - } + public String getArtistId() { + return artistId; + } - public void setArtistId(String artistId) { - this.artistId = artistId; - } + public void setArtistId(String artistId) { + this.artistId = artistId; + } public boolean isDirectory() { return directory; @@ -375,17 +375,17 @@ public class MusicDirectory implements Serializable { return album; } - public boolean isAlbum() { - return getParent() != null || getArtist() != null; - } + public boolean isAlbum() { + return getParent() != null || getArtist() != null; + } - public String getAlbumDisplay() { - if(album != null && title.startsWith("Disc ")) { - return album; - } else { - return title; - } - } + public String getAlbumDisplay() { + if(album != null && title.startsWith("Disc ")) { + return album; + } else { + return title; + } + } public void setAlbum(String album) { this.album = album; @@ -495,43 +495,43 @@ public class MusicDirectory implements Serializable { this.path = path; } - public Integer getDiscNumber() { - return discNumber; - } - - public void setDiscNumber(Integer discNumber) { - this.discNumber = discNumber; - } - - public int getType() { - return type; - } - public void setType(int type) { - this.type = type; - } - public boolean isSong() { - return type == TYPE_SONG; - } + public Integer getDiscNumber() { + return discNumber; + } - public int getCloseness() { - return closeness; - } + public void setDiscNumber(Integer discNumber) { + this.discNumber = discNumber; + } - public void setCloseness(int closeness) { - this.closeness = closeness; - } + public int getType() { + return type; + } + public void setType(int type) { + this.type = type; + } + public boolean isSong() { + return type == TYPE_SONG; + } - public boolean isOnlineId(Context context) { - try { - String cacheLocation = Util.getPreferences(context).getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null); - return cacheLocation == null || id == null || id.indexOf(cacheLocation) == -1; - } catch(Exception e) { - Log.w(TAG, "Failed to check online id validity"); + public int getCloseness() { + return closeness; + } - // Err on the side of default functionality - return true; - } - } + public void setCloseness(int closeness) { + this.closeness = closeness; + } + + public boolean isOnlineId(Context context) { + try { + String cacheLocation = Util.getPreferences(context).getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null); + return cacheLocation == null || id == null || id.indexOf(cacheLocation) == -1; + } catch(Exception e) { + Log.w(TAG, "Failed to check online id validity"); + + // Err on the side of default functionality + return true; + } + } @Override public boolean equals(Object o) { @@ -555,72 +555,72 @@ public class MusicDirectory implements Serializable { public String toString() { return title; } - } - - public static class EntryComparator implements Comparator { - private boolean byYear; - private Collator collator; - - public EntryComparator(boolean byYear) { - this.byYear = byYear; - this.collator = Collator.getInstance(Locale.US); - this.collator.setStrength(Collator.PRIMARY); - } - - public int compare(Entry lhs, Entry rhs) { - if(lhs.isDirectory() && !rhs.isDirectory()) { - return -1; - } else if(!lhs.isDirectory() && rhs.isDirectory()) { - return 1; - } else if(lhs.isDirectory() && rhs.isDirectory()) { - if(byYear) { - Integer lhsYear = lhs.getYear(); - Integer rhsYear = rhs.getYear(); - if(lhsYear != null && rhsYear != null) { - return lhsYear.compareTo(rhsYear); - } else if(lhsYear != null) { - return -1; - } else if(rhsYear != null) { - return 1; - } - } + } - return collator.compare(lhs.getAlbumDisplay(), rhs.getAlbumDisplay()); - } - - Integer lhsDisc = lhs.getDiscNumber(); - Integer rhsDisc = rhs.getDiscNumber(); - - if(lhsDisc != null && rhsDisc != null) { - if(lhsDisc < rhsDisc) { - return -1; - } else if(lhsDisc > rhsDisc) { - return 1; - } - } - - Integer lhsTrack = lhs.getTrack(); - Integer rhsTrack = rhs.getTrack(); - if(lhsTrack != null && rhsTrack != null && lhsTrack != rhsTrack) { - return lhsTrack.compareTo(rhsTrack); - } else if(lhsTrack != null) { - return -1; - } else if(rhsTrack != null) { - return 1; - } + public static class EntryComparator implements Comparator { + private boolean byYear; + private Collator collator; - return collator.compare(lhs.getTitle(), rhs.getTitle()); - } - - public static void sort(List entries) { - sort(entries, true); - } - public static void sort(List entries, boolean byYear) { - try { - Collections.sort(entries, new EntryComparator(byYear)); - } catch (Exception e) { - Log.w(TAG, "Failed to sort MusicDirectory"); - } - } - } + public EntryComparator(boolean byYear) { + this.byYear = byYear; + this.collator = Collator.getInstance(Locale.US); + this.collator.setStrength(Collator.PRIMARY); + } + + public int compare(Entry lhs, Entry rhs) { + if(lhs.isDirectory() && !rhs.isDirectory()) { + return -1; + } else if(!lhs.isDirectory() && rhs.isDirectory()) { + return 1; + } else if(lhs.isDirectory() && rhs.isDirectory()) { + if(byYear) { + Integer lhsYear = lhs.getYear(); + Integer rhsYear = rhs.getYear(); + if(lhsYear != null && rhsYear != null) { + return lhsYear.compareTo(rhsYear); + } else if(lhsYear != null) { + return -1; + } else if(rhsYear != null) { + return 1; + } + } + + return collator.compare(lhs.getAlbumDisplay(), rhs.getAlbumDisplay()); + } + + Integer lhsDisc = lhs.getDiscNumber(); + Integer rhsDisc = rhs.getDiscNumber(); + + if(lhsDisc != null && rhsDisc != null) { + if(lhsDisc < rhsDisc) { + return -1; + } else if(lhsDisc > rhsDisc) { + return 1; + } + } + + Integer lhsTrack = lhs.getTrack(); + Integer rhsTrack = rhs.getTrack(); + if(lhsTrack != null && rhsTrack != null && lhsTrack != rhsTrack) { + return lhsTrack.compareTo(rhsTrack); + } else if(lhsTrack != null) { + return -1; + } else if(rhsTrack != null) { + return 1; + } + + return collator.compare(lhs.getTitle(), rhs.getTitle()); + } + + public static void sort(List entries) { + sort(entries, true); + } + public static void sort(List entries, boolean byYear) { + try { + Collections.sort(entries, new EntryComparator(byYear)); + } catch (Exception e) { + Log.w(TAG, "Failed to sort MusicDirectory"); + } + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/domain/MusicFolder.java b/app/src/main/java/net/nullsum/audinaut/domain/MusicFolder.java index 8bc2a5f..0524b6e 100644 --- a/app/src/main/java/net/nullsum/audinaut/domain/MusicFolder.java +++ b/app/src/main/java/net/nullsum/audinaut/domain/MusicFolder.java @@ -32,49 +32,49 @@ import java.util.List; * @version $Id$ */ public class MusicFolder implements Serializable { - private static final String TAG = MusicFolder.class.getSimpleName(); - private String id; - private String name; - private boolean enabled; + private static final String TAG = MusicFolder.class.getSimpleName(); + private String id; + private String name; + private boolean enabled; - public MusicFolder() { + public MusicFolder() { - } - public MusicFolder(String id, String name) { - this.id = id; - this.name = name; - } + } + public MusicFolder(String id, String name) { + this.id = id; + this.name = name; + } - public String getId() { - return id; - } + public String getId() { + return id; + } - public String getName() { - return name; - } + public String getName() { + return name; + } - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - public boolean getEnabled() { - return enabled; - } + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + public boolean getEnabled() { + return enabled; + } - public static class MusicFolderComparator implements Comparator { - public int compare(MusicFolder lhsMusicFolder, MusicFolder rhsMusicFolder) { - if(lhsMusicFolder == rhsMusicFolder || lhsMusicFolder.getName().equals(rhsMusicFolder.getName())) { - return 0; - } else { - return lhsMusicFolder.getName().compareToIgnoreCase(rhsMusicFolder.getName()); - } - } - } + public static class MusicFolderComparator implements Comparator { + public int compare(MusicFolder lhsMusicFolder, MusicFolder rhsMusicFolder) { + if(lhsMusicFolder == rhsMusicFolder || lhsMusicFolder.getName().equals(rhsMusicFolder.getName())) { + return 0; + } else { + return lhsMusicFolder.getName().compareToIgnoreCase(rhsMusicFolder.getName()); + } + } + } - public static void sort(List musicFolders) { - try { - Collections.sort(musicFolders, new MusicFolderComparator()); - } catch (Exception e) { - Log.w(TAG, "Failed to sort music folders", e); - } - } + public static void sort(List musicFolders) { + try { + Collections.sort(musicFolders, new MusicFolderComparator()); + } catch (Exception e) { + Log.w(TAG, "Failed to sort music folders", e); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/domain/PlayerQueue.java b/app/src/main/java/net/nullsum/audinaut/domain/PlayerQueue.java index 673bb38..827f27b 100644 --- a/app/src/main/java/net/nullsum/audinaut/domain/PlayerQueue.java +++ b/app/src/main/java/net/nullsum/audinaut/domain/PlayerQueue.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.domain; @@ -21,10 +21,10 @@ import java.util.Date; import java.util.List; public class PlayerQueue implements Serializable { - public List songs = new ArrayList(); - public List toDelete = new ArrayList(); - public int currentPlayingIndex; - public int currentPlayingPosition; - public boolean renameCurrent = false; - public Date changed = null; + public List songs = new ArrayList(); + public List toDelete = new ArrayList(); + public int currentPlayingIndex; + public int currentPlayingPosition; + public boolean renameCurrent = false; + public Date changed = null; } diff --git a/app/src/main/java/net/nullsum/audinaut/domain/Playlist.java b/app/src/main/java/net/nullsum/audinaut/domain/Playlist.java index 5ecf7a1..86708dd 100644 --- a/app/src/main/java/net/nullsum/audinaut/domain/Playlist.java +++ b/app/src/main/java/net/nullsum/audinaut/domain/Playlist.java @@ -34,31 +34,31 @@ public class Playlist implements Serializable { private String id; private String name; - private String owner; - private String comment; - private String songCount; - private Boolean pub; - private Date created; - private Date changed; - private Integer duration; + private String owner; + private String comment; + private String songCount; + private Boolean pub; + private Date created; + private Date changed; + private Integer duration; - public Playlist() { + public Playlist() { - } + } public Playlist(String id, String name) { this.id = id; this.name = name; } - public Playlist(String id, String name, String owner, String comment, String songCount, String pub, String created, String changed, Integer duration) { + public Playlist(String id, String name, String owner, String comment, String songCount, String pub, String created, String changed, Integer duration) { this.id = id; this.name = name; - this.owner = (owner == null) ? "" : owner; - this.comment = (comment == null) ? "" : comment; - this.songCount = (songCount == null) ? "" : songCount; - this.pub = (pub == null) ? null : (pub.equals("true")); - setCreated(created); - setChanged(changed); - this.duration = duration; + this.owner = (owner == null) ? "" : owner; + this.comment = (comment == null) ? "" : comment; + this.songCount = (songCount == null) ? "" : songCount; + this.pub = (pub == null) ? null : (pub.equals("true")); + setCreated(created); + setChanged(changed); + this.duration = duration; } public String getId() { @@ -76,112 +76,112 @@ public class Playlist implements Serializable { public void setName(String name) { this.name = name; } - - public String getOwner() { - return this.owner; - } - - public void setOwner(String owner) { - this.owner = owner; - } - - public String getComment() { - return this.comment; - } - - public void setComment(String comment) { - this.comment = comment; - } - - public String getSongCount() { - return this.songCount; - } - - public void setSongCount(String songCount) { - this.songCount = songCount; - } - - public Boolean getPublic() { - return this.pub; - } - public void setPublic(Boolean pub) { - this.pub = pub; - } - public Date getCreated() { - return created; - } + public String getOwner() { + return this.owner; + } - public void setCreated(String created) { - if (created != null) { - try { - this.created = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(created); - } catch (ParseException e) { - this.created = null; - } - } else { - this.created = null; - } - } - public void setCreated(Date created) { - this.created = created; - } + public void setOwner(String owner) { + this.owner = owner; + } - public Date getChanged() { - return changed; - } - public void setChanged(String changed) { - if (changed != null) { - try { - this.changed = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(changed); - } catch (ParseException e) { - this.changed = null; - } - } else { - this.changed = null; - } - } - public void setChanged(Date changed) { - this.changed = changed; - } + public String getComment() { + return this.comment; + } - public Integer getDuration() { - return duration; - } - public void setDuration(Integer duration) { - this.duration = duration; - } + public void setComment(String comment) { + this.comment = comment; + } - @Override - public String toString() { - return name; - } - - @Override - public boolean equals(Object o) { - if(o == this) { - return true; - } else if(o == null) { - return false; - } else if(o instanceof String) { - return o.equals(this.id); - } else if(o.getClass() != getClass()) { - return false; - } - - Playlist playlist = (Playlist) o; - return playlist.id.equals(this.id); - } + public String getSongCount() { + return this.songCount; + } - public static class PlaylistComparator implements Comparator { - @Override - public int compare(Playlist playlist1, Playlist playlist2) { - return playlist1.getName().compareToIgnoreCase(playlist2.getName()); - } + public void setSongCount(String songCount) { + this.songCount = songCount; + } - public static List sort(List playlists) { - Collections.sort(playlists, new PlaylistComparator()); - return playlists; - } - } + public Boolean getPublic() { + return this.pub; + } + public void setPublic(Boolean pub) { + this.pub = pub; + } + + public Date getCreated() { + return created; + } + + public void setCreated(String created) { + if (created != null) { + try { + this.created = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(created); + } catch (ParseException e) { + this.created = null; + } + } else { + this.created = null; + } + } + public void setCreated(Date created) { + this.created = created; + } + + public Date getChanged() { + return changed; + } + public void setChanged(String changed) { + if (changed != null) { + try { + this.changed = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(changed); + } catch (ParseException e) { + this.changed = null; + } + } else { + this.changed = null; + } + } + public void setChanged(Date changed) { + this.changed = changed; + } + + public Integer getDuration() { + return duration; + } + public void setDuration(Integer duration) { + this.duration = duration; + } + + @Override + public String toString() { + return name; + } + + @Override + public boolean equals(Object o) { + if(o == this) { + return true; + } else if(o == null) { + return false; + } else if(o instanceof String) { + return o.equals(this.id); + } else if(o.getClass() != getClass()) { + return false; + } + + Playlist playlist = (Playlist) o; + return playlist.id.equals(this.id); + } + + public static class PlaylistComparator implements Comparator { + @Override + public int compare(Playlist playlist1, Playlist playlist2) { + return playlist1.getName().compareToIgnoreCase(playlist2.getName()); + } + + public static List sort(List playlists) { + Collections.sort(playlists, new PlaylistComparator()); + return playlists; + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/domain/SearchCritera.java b/app/src/main/java/net/nullsum/audinaut/domain/SearchCritera.java index 9dac45b..beacdb3 100644 --- a/app/src/main/java/net/nullsum/audinaut/domain/SearchCritera.java +++ b/app/src/main/java/net/nullsum/audinaut/domain/SearchCritera.java @@ -27,67 +27,67 @@ import java.util.regex.Pattern; */ public class SearchCritera { - private final String query; - private final int artistCount; - private final int albumCount; - private final int songCount; - private Pattern pattern; + private final String query; + private final int artistCount; + private final int albumCount; + private final int songCount; + private Pattern pattern; - public SearchCritera(String query, int artistCount, int albumCount, int songCount) { - this.query = query; - this.artistCount = artistCount; - this.albumCount = albumCount; - this.songCount = songCount; - } + public SearchCritera(String query, int artistCount, int albumCount, int songCount) { + this.query = query; + this.artistCount = artistCount; + this.albumCount = albumCount; + this.songCount = songCount; + } - public String getQuery() { - return query; - } + public String getQuery() { + return query; + } - public int getArtistCount() { - return artistCount; - } + public int getArtistCount() { + return artistCount; + } - public int getAlbumCount() { - return albumCount; - } + public int getAlbumCount() { + return albumCount; + } - public int getSongCount() { - return songCount; - } + public int getSongCount() { + return songCount; + } - /** - * Returns and caches a pattern instance that can be used to check if a - * string matches the query. - */ - public Pattern getPattern() { + /** + * Returns and caches a pattern instance that can be used to check if a + * string matches the query. + */ + public Pattern getPattern() { - // If the pattern wasn't already cached, create a new regular expression - // from the search string : - // * Surround the search string with ".*" (match anything) - // * Replace spaces and wildcard '*' characters with ".*" - // * All other characters are properly quoted - if (this.pattern == null) { - String regex = ".*"; - String currentPart = ""; - for (int i = 0; i < query.length(); i++) { - char c = query.charAt(i); - if (c == '*' || c == ' ') { - regex += Pattern.quote(currentPart); - regex += ".*"; - currentPart = ""; - } else { - currentPart += c; - } - } - if (currentPart.length() > 0) { - regex += Pattern.quote(currentPart); - } + // If the pattern wasn't already cached, create a new regular expression + // from the search string : + // * Surround the search string with ".*" (match anything) + // * Replace spaces and wildcard '*' characters with ".*" + // * All other characters are properly quoted + if (this.pattern == null) { + String regex = ".*"; + String currentPart = ""; + for (int i = 0; i < query.length(); i++) { + char c = query.charAt(i); + if (c == '*' || c == ' ') { + regex += Pattern.quote(currentPart); + regex += ".*"; + currentPart = ""; + } else { + currentPart += c; + } + } + if (currentPart.length() > 0) { + regex += Pattern.quote(currentPart); + } - regex += ".*"; - this.pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); - } + regex += ".*"; + this.pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); + } - return this.pattern; - } + return this.pattern; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/domain/SearchResult.java b/app/src/main/java/net/nullsum/audinaut/domain/SearchResult.java index 68186c7..18835f6 100644 --- a/app/src/main/java/net/nullsum/audinaut/domain/SearchResult.java +++ b/app/src/main/java/net/nullsum/audinaut/domain/SearchResult.java @@ -50,13 +50,13 @@ public class SearchResult implements Serializable { return songs; } - public boolean hasArtists() { - return !artists.isEmpty(); - } - public boolean hasAlbums() { - return !albums.isEmpty(); - } - public boolean hasSongs() { - return !songs.isEmpty(); - } -} \ No newline at end of file + public boolean hasArtists() { + return !artists.isEmpty(); + } + public boolean hasAlbums() { + return !albums.isEmpty(); + } + public boolean hasSongs() { + return !songs.isEmpty(); + } +} diff --git a/app/src/main/java/net/nullsum/audinaut/domain/User.java b/app/src/main/java/net/nullsum/audinaut/domain/User.java index 02f5399..cf0b15c 100644 --- a/app/src/main/java/net/nullsum/audinaut/domain/User.java +++ b/app/src/main/java/net/nullsum/audinaut/domain/User.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.domain; @@ -22,125 +22,125 @@ import java.util.ArrayList; import java.util.List; public class User implements Serializable { - public static final String ADMIN = "adminRole"; - public static final String SETTINGS = "settingsRole"; - public static final String DOWNLOAD = "downloadRole"; - public static final String UPLOAD = "uploadRole"; - public static final String COVERART = "coverArtRole"; - public static final String COMMENT = "commentRole"; - public static final String STREAM = "streamRole"; - public static final List ROLES = new ArrayList<>(); - - static { - ROLES.add(ADMIN); - ROLES.add(SETTINGS); - ROLES.add(STREAM); - ROLES.add(DOWNLOAD); - ROLES.add(UPLOAD); - ROLES.add(COVERART); - ROLES.add(COMMENT); - } - - private String username; - private String password; - private String email; + public static final String ADMIN = "adminRole"; + public static final String SETTINGS = "settingsRole"; + public static final String DOWNLOAD = "downloadRole"; + public static final String UPLOAD = "uploadRole"; + public static final String COVERART = "coverArtRole"; + public static final String COMMENT = "commentRole"; + public static final String STREAM = "streamRole"; + public static final List ROLES = new ArrayList<>(); - private List settings = new ArrayList(); - private List musicFolders; + static { + ROLES.add(ADMIN); + ROLES.add(SETTINGS); + ROLES.add(STREAM); + ROLES.add(DOWNLOAD); + ROLES.add(UPLOAD); + ROLES.add(COVERART); + ROLES.add(COMMENT); + } - public User() { + private String username; + private String password; + private String email; - } + private List settings = new ArrayList(); + private List musicFolders; - public String getUsername() { - return username; - } + public User() { - public void setUsername(String username) { - this.username = username; - } + } - public String getPassword() { - return password; - } + public String getUsername() { + return username; + } - public void setPassword(String password) { - this.password = password; - } + public void setUsername(String username) { + this.username = username; + } - public String getEmail() { - return email; - } + public String getPassword() { + return password; + } - public void setEmail(String email) { - this.email = email; - } + public void setPassword(String password) { + this.password = password; + } - public List getSettings() { - return settings; - } - public void setSettings(List settings) { - this.settings.clear(); - this.settings.addAll(settings); - } - public void addSetting(String name, Boolean value) { - settings.add(new Setting(name, value)); - } + public String getEmail() { + return email; + } - public void addMusicFolder(MusicFolder musicFolder) { - if(musicFolders == null) { - musicFolders = new ArrayList<>(); - } + public void setEmail(String email) { + this.email = email; + } - musicFolders.add(new MusicFolderSetting(musicFolder.getId(), musicFolder.getName(), false)); - } - public void addMusicFolder(MusicFolderSetting musicFolderSetting, boolean defaultValue) { - if(musicFolders == null) { - musicFolders = new ArrayList<>(); - } + public List getSettings() { + return settings; + } + public void setSettings(List settings) { + this.settings.clear(); + this.settings.addAll(settings); + } + public void addSetting(String name, Boolean value) { + settings.add(new Setting(name, value)); + } - musicFolders.add(new MusicFolderSetting(musicFolderSetting.getName(), musicFolderSetting.getLabel(), defaultValue)); - } - public List getMusicFolderSettings() { - return musicFolders; - } + public void addMusicFolder(MusicFolder musicFolder) { + if(musicFolders == null) { + musicFolders = new ArrayList<>(); + } - public static class Setting implements Serializable { - private String name; - private Boolean value; + musicFolders.add(new MusicFolderSetting(musicFolder.getId(), musicFolder.getName(), false)); + } + public void addMusicFolder(MusicFolderSetting musicFolderSetting, boolean defaultValue) { + if(musicFolders == null) { + musicFolders = new ArrayList<>(); + } - public Setting() { - - } - public Setting(String name, Boolean value) { - this.name = name; - this.value = value; - } + musicFolders.add(new MusicFolderSetting(musicFolderSetting.getName(), musicFolderSetting.getLabel(), defaultValue)); + } + public List getMusicFolderSettings() { + return musicFolders; + } - public String getName() { - return name; - } - public Boolean getValue() { - return value; - } - public void setValue(Boolean value) { - this.value = value; - } - } + public static class Setting implements Serializable { + private String name; + private Boolean value; - public static class MusicFolderSetting extends Setting { - private String label; + public Setting() { - public MusicFolderSetting() { + } + public Setting(String name, Boolean value) { + this.name = name; + this.value = value; + } - } - public MusicFolderSetting(String name, String label, Boolean value) { - super(name, value); - this.label = label; - } + public String getName() { + return name; + } + public Boolean getValue() { + return value; + } + public void setValue(Boolean value) { + this.value = value; + } + } - public String getLabel() { - return label; - } - } + public static class MusicFolderSetting extends Setting { + private String label; + + public MusicFolderSetting() { + + } + public MusicFolderSetting(String name, String label, Boolean value) { + super(name, value); + this.label = label; + } + + public String getLabel() { + return label; + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/DownloadFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/DownloadFragment.java index 2363e5d..6c1ea72 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/DownloadFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/DownloadFragment.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.fragments; @@ -46,145 +46,145 @@ import net.nullsum.audinaut.adapter.DownloadFileAdapter; import net.nullsum.audinaut.view.UpdateView; public class DownloadFragment extends SelectRecyclerFragment implements SectionAdapter.OnItemClickedListener { - private long currentRevision; - private ScheduledExecutorService executorService; + private long currentRevision; + private ScheduledExecutorService executorService; - public DownloadFragment() { - serialize = false; - pullToRefresh = false; - } + public DownloadFragment() { + serialize = false; + pullToRefresh = false; + } - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - super.onCreateView(inflater, container, bundle); + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { + super.onCreateView(inflater, container, bundle); - ItemTouchHelper touchHelper = new ItemTouchHelper(new DownloadFileItemHelperCallback(this, false)); - touchHelper.attachToRecyclerView(recyclerView); + ItemTouchHelper touchHelper = new ItemTouchHelper(new DownloadFileItemHelperCallback(this, false)); + touchHelper.attachToRecyclerView(recyclerView); - return rootView; - } + return rootView; + } - @Override - public void onResume() { - super.onResume(); + @Override + public void onResume() { + super.onResume(); - final Handler handler = new Handler(); - Runnable runnable = new Runnable() { - @Override - public void run() { - handler.post(new Runnable() { - @Override - public void run() { - update(); - } - }); - } - }; + final Handler handler = new Handler(); + Runnable runnable = new Runnable() { + @Override + public void run() { + handler.post(new Runnable() { + @Override + public void run() { + update(); + } + }); + } + }; - executorService = Executors.newSingleThreadScheduledExecutor(); - executorService.scheduleWithFixedDelay(runnable, 0L, 1000L, TimeUnit.MILLISECONDS); - } + executorService = Executors.newSingleThreadScheduledExecutor(); + executorService.scheduleWithFixedDelay(runnable, 0L, 1000L, TimeUnit.MILLISECONDS); + } - @Override - public void onPause() { - super.onPause(); - executorService.shutdown(); - } + @Override + public void onPause() { + super.onPause(); + executorService.shutdown(); + } - @Override - public int getOptionsMenu() { - return R.menu.downloading; - } + @Override + public int getOptionsMenu() { + return R.menu.downloading; + } - @Override - public SectionAdapter getAdapter(List objs) { - return new DownloadFileAdapter(context, objs, this); - } + @Override + public SectionAdapter getAdapter(List objs) { + return new DownloadFileAdapter(context, objs, this); + } - @Override - public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { - DownloadService downloadService = getDownloadService(); - if(downloadService == null) { - return new ArrayList(); - } + @Override + public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { + DownloadService downloadService = getDownloadService(); + if(downloadService == null) { + return new ArrayList(); + } - List songList = new ArrayList(); - songList.addAll(downloadService.getBackgroundDownloads()); - currentRevision = downloadService.getDownloadListUpdateRevision(); - return songList; - } + List songList = new ArrayList(); + songList.addAll(downloadService.getBackgroundDownloads()); + currentRevision = downloadService.getDownloadListUpdateRevision(); + return songList; + } - @Override - public int getTitleResource() { - return R.string.button_bar_downloading; - } + @Override + public int getTitleResource() { + return R.string.button_bar_downloading; + } - @Override - public void onItemClicked(UpdateView updateView, DownloadFile item) { + @Override + public void onItemClicked(UpdateView updateView, DownloadFile item) { - } + } - @Override - public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, DownloadFile downloadFile) { - MusicDirectory.Entry selectedItem = downloadFile.getSong(); - onCreateContextMenuSupport(menu, menuInflater, updateView, selectedItem); - if(!Util.isOffline(context)) { - menu.removeItem(R.id.song_menu_remove_playlist); - } + @Override + public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, DownloadFile downloadFile) { + MusicDirectory.Entry selectedItem = downloadFile.getSong(); + onCreateContextMenuSupport(menu, menuInflater, updateView, selectedItem); + if(!Util.isOffline(context)) { + menu.removeItem(R.id.song_menu_remove_playlist); + } - recreateContextMenu(menu); - } + recreateContextMenu(menu); + } - @Override - public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, DownloadFile downloadFile) { - MusicDirectory.Entry selectedItem = downloadFile.getSong(); - return onContextItemSelected(menuItem, selectedItem); - } + @Override + public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, DownloadFile downloadFile) { + MusicDirectory.Entry selectedItem = downloadFile.getSong(); + return onContextItemSelected(menuItem, selectedItem); + } - @Override - public boolean onOptionsItemSelected(MenuItem menuItem) { - if(super.onOptionsItemSelected(menuItem)) { - return true; - } + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + if(super.onOptionsItemSelected(menuItem)) { + return true; + } - switch (menuItem.getItemId()) { - case R.id.menu_remove_all: - Util.confirmDialog(context, R.string.download_menu_remove_all, "", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - getDownloadService().clearBackground(); - return null; - } + switch (menuItem.getItemId()) { + case R.id.menu_remove_all: + Util.confirmDialog(context, R.string.download_menu_remove_all, "", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + getDownloadService().clearBackground(); + return null; + } - @Override - protected void done(Void result) { - update(); - } - }.execute(); - } - }); - return true; - } + @Override + protected void done(Void result) { + update(); + } + }.execute(); + } + }); + return true; + } - return false; - } + return false; + } - private void update() { - DownloadService downloadService = getDownloadService(); - if (downloadService == null || objects == null || adapter == null) { - return; - } + private void update() { + DownloadService downloadService = getDownloadService(); + if (downloadService == null || objects == null || adapter == null) { + return; + } - if (currentRevision != downloadService.getDownloadListUpdateRevision()) { - List downloadFileList = downloadService.getBackgroundDownloads(); - objects.clear(); - objects.addAll(downloadFileList); - adapter.notifyDataSetChanged(); + if (currentRevision != downloadService.getDownloadListUpdateRevision()) { + List downloadFileList = downloadService.getBackgroundDownloads(); + objects.clear(); + objects.addAll(downloadFileList); + adapter.notifyDataSetChanged(); - currentRevision = downloadService.getDownloadListUpdateRevision(); - } - } + currentRevision = downloadService.getDownloadListUpdateRevision(); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/EqualizerFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/EqualizerFragment.java index c659f15..e17c8b8 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/EqualizerFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/EqualizerFragment.java @@ -48,412 +48,412 @@ import net.nullsum.audinaut.util.Util; * Created by Scott on 10/27/13. */ public class EqualizerFragment extends SubsonicFragment { - private static final String TAG = EqualizerFragment.class.getSimpleName(); + private static final String TAG = EqualizerFragment.class.getSimpleName(); - private static final int MENU_GROUP_PRESET = 100; + private static final int MENU_GROUP_PRESET = 100; - private final Map bars = new HashMap(); - private SeekBar bassBar; - private SeekBar loudnessBar; - private EqualizerController equalizerController; - private Equalizer equalizer; - private BassBoost bass; - private LoudnessEnhancerController loudnessEnhancer; - private short masterLevel = 0; + private final Map bars = new HashMap(); + private SeekBar bassBar; + private SeekBar loudnessBar; + private EqualizerController equalizerController; + private Equalizer equalizer; + private BassBoost bass; + private LoudnessEnhancerController loudnessEnhancer; + private short masterLevel = 0; - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - rootView = inflater.inflate(R.layout.equalizer, container, false); + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { + rootView = inflater.inflate(R.layout.equalizer, container, false); - try { - DownloadService service = DownloadService.getInstance(); - equalizerController = service.getEqualizerController(); - equalizer = equalizerController.getEqualizer(); - bass = equalizerController.getBassBoost(); - loudnessEnhancer = equalizerController.getLoudnessEnhancerController(); + try { + DownloadService service = DownloadService.getInstance(); + equalizerController = service.getEqualizerController(); + equalizer = equalizerController.getEqualizer(); + bass = equalizerController.getBassBoost(); + loudnessEnhancer = equalizerController.getLoudnessEnhancerController(); - initEqualizer(); - } catch(Exception e) { - Log.e(TAG, "Failed to initialize EQ", e); - Util.toast(context, "Failed to initialize EQ"); - context.onBackPressed(); - } + initEqualizer(); + } catch(Exception e) { + Log.e(TAG, "Failed to initialize EQ", e); + Util.toast(context, "Failed to initialize EQ"); + context.onBackPressed(); + } - final View presetButton = rootView.findViewById(R.id.equalizer_preset); - registerForContextMenu(presetButton); - presetButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - presetButton.showContextMenu(); - } - }); + final View presetButton = rootView.findViewById(R.id.equalizer_preset); + registerForContextMenu(presetButton); + presetButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + presetButton.showContextMenu(); + } + }); - CheckBox enabledCheckBox = (CheckBox) rootView.findViewById(R.id.equalizer_enabled); - enabledCheckBox.setChecked(equalizer.getEnabled()); - enabledCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean b) { - try { - setEqualizerEnabled(b); - } catch(Exception e) { - Log.e(TAG, "Failed to set EQ enabled", e); - Util.toast(context, "Failed to set EQ enabled"); - context.onBackPressed(); - } - } - }); + CheckBox enabledCheckBox = (CheckBox) rootView.findViewById(R.id.equalizer_enabled); + enabledCheckBox.setChecked(equalizer.getEnabled()); + enabledCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean b) { + try { + setEqualizerEnabled(b); + } catch(Exception e) { + Log.e(TAG, "Failed to set EQ enabled", e); + Util.toast(context, "Failed to set EQ enabled"); + context.onBackPressed(); + } + } + }); - setTitle(R.string.equalizer_label); - setSubtitle(null); + setTitle(R.string.equalizer_label); + setSubtitle(null); - return rootView; - } + return rootView; + } - @Override - public void onPause() { - super.onPause(); + @Override + public void onPause() { + super.onPause(); - try { - equalizerController.saveSettings(); + try { + equalizerController.saveSettings(); - if (!equalizer.getEnabled()) { - equalizerController.release(); - } - } catch(Exception e) { - Log.w(TAG, "Failed to release controller", e); - } - } + if (!equalizer.getEnabled()) { + equalizerController.release(); + } + } catch(Exception e) { + Log.w(TAG, "Failed to release controller", e); + } + } - @Override - public void onResume() { - super.onResume(); - equalizerController = DownloadService.getInstance().getEqualizerController(); - equalizer = equalizerController.getEqualizer(); - bass = equalizerController.getBassBoost(); - } + @Override + public void onResume() { + super.onResume(); + equalizerController = DownloadService.getInstance().getEqualizerController(); + equalizer = equalizerController.getEqualizer(); + bass = equalizerController.getBassBoost(); + } - @Override - public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { - super.onCreateContextMenu(menu, view, menuInfo); - if(!primaryFragment) { - return; - } + @Override + public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) { + super.onCreateContextMenu(menu, view, menuInfo); + if(!primaryFragment) { + return; + } - short currentPreset; - try { - currentPreset = equalizer.getCurrentPreset(); - } catch (Exception x) { - currentPreset = -1; - } + short currentPreset; + try { + currentPreset = equalizer.getCurrentPreset(); + } catch (Exception x) { + currentPreset = -1; + } - for (short preset = 0; preset < equalizer.getNumberOfPresets(); preset++) { - MenuItem menuItem = menu.add(MENU_GROUP_PRESET, preset, preset, equalizer.getPresetName(preset)); - if (preset == currentPreset) { - menuItem.setChecked(true); - } - } - menu.setGroupCheckable(MENU_GROUP_PRESET, true, true); - } + for (short preset = 0; preset < equalizer.getNumberOfPresets(); preset++) { + MenuItem menuItem = menu.add(MENU_GROUP_PRESET, preset, preset, equalizer.getPresetName(preset)); + if (preset == currentPreset) { + menuItem.setChecked(true); + } + } + menu.setGroupCheckable(MENU_GROUP_PRESET, true, true); + } - @Override - public boolean onContextItemSelected(MenuItem menuItem) { - short preset = (short) menuItem.getItemId(); - for(int i = 0; i < 10; i++) { - try { - equalizer.usePreset(preset); - i = 10; - } catch (UnsupportedOperationException e) { - equalizerController.release(); - equalizer = equalizerController.getEqualizer(); - bass = equalizerController.getBassBoost(); - loudnessEnhancer = equalizerController.getLoudnessEnhancerController(); - } - } - updateBars(false); - return true; - } + @Override + public boolean onContextItemSelected(MenuItem menuItem) { + short preset = (short) menuItem.getItemId(); + for(int i = 0; i < 10; i++) { + try { + equalizer.usePreset(preset); + i = 10; + } catch (UnsupportedOperationException e) { + equalizerController.release(); + equalizer = equalizerController.getEqualizer(); + bass = equalizerController.getBassBoost(); + loudnessEnhancer = equalizerController.getLoudnessEnhancerController(); + } + } + updateBars(false); + return true; + } - private void setEqualizerEnabled(boolean enabled) { - SharedPreferences prefs = Util.getPreferences(context); - SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(Constants.PREFERENCES_EQUALIZER_ON, enabled); - editor.apply(); - for(int i = 0; i < 10; i++) { - try { - equalizer.setEnabled(enabled); - updateBars(true); - i = 10; - } catch (UnsupportedOperationException e) { - equalizerController.release(); - equalizer = equalizerController.getEqualizer(); - bass = equalizerController.getBassBoost(); - loudnessEnhancer = equalizerController.getLoudnessEnhancerController(); - } - } - } + private void setEqualizerEnabled(boolean enabled) { + SharedPreferences prefs = Util.getPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean(Constants.PREFERENCES_EQUALIZER_ON, enabled); + editor.apply(); + for(int i = 0; i < 10; i++) { + try { + equalizer.setEnabled(enabled); + updateBars(true); + i = 10; + } catch (UnsupportedOperationException e) { + equalizerController.release(); + equalizer = equalizerController.getEqualizer(); + bass = equalizerController.getBassBoost(); + loudnessEnhancer = equalizerController.getLoudnessEnhancerController(); + } + } + } - private void updateBars(boolean changedEnabled) { - try { - boolean isEnabled = equalizer.getEnabled(); - short minEQLevel = equalizer.getBandLevelRange()[0]; - short maxEQLevel = equalizer.getBandLevelRange()[1]; - for (Map.Entry entry : bars.entrySet()) { - short band = entry.getKey(); - SeekBar bar = entry.getValue(); - bar.setEnabled(isEnabled); - if (band >= (short) 0) { - short setLevel; - if (changedEnabled) { - setLevel = (short) (equalizer.getBandLevel(band) - masterLevel); - if (isEnabled) { - bar.setProgress(equalizer.getBandLevel(band) - minEQLevel); - } else { - bar.setProgress(-minEQLevel); - } - } else { - bar.setProgress(equalizer.getBandLevel(band) - minEQLevel); - setLevel = (short) (equalizer.getBandLevel(band) + masterLevel); - } - if (setLevel < minEQLevel) { - setLevel = minEQLevel; - } else if (setLevel > maxEQLevel) { - setLevel = maxEQLevel; - } - equalizer.setBandLevel(band, setLevel); - } else if (!isEnabled) { - bar.setProgress(-minEQLevel); - } - } + private void updateBars(boolean changedEnabled) { + try { + boolean isEnabled = equalizer.getEnabled(); + short minEQLevel = equalizer.getBandLevelRange()[0]; + short maxEQLevel = equalizer.getBandLevelRange()[1]; + for (Map.Entry entry : bars.entrySet()) { + short band = entry.getKey(); + SeekBar bar = entry.getValue(); + bar.setEnabled(isEnabled); + if (band >= (short) 0) { + short setLevel; + if (changedEnabled) { + setLevel = (short) (equalizer.getBandLevel(band) - masterLevel); + if (isEnabled) { + bar.setProgress(equalizer.getBandLevel(band) - minEQLevel); + } else { + bar.setProgress(-minEQLevel); + } + } else { + bar.setProgress(equalizer.getBandLevel(band) - minEQLevel); + setLevel = (short) (equalizer.getBandLevel(band) + masterLevel); + } + if (setLevel < minEQLevel) { + setLevel = minEQLevel; + } else if (setLevel > maxEQLevel) { + setLevel = maxEQLevel; + } + equalizer.setBandLevel(band, setLevel); + } else if (!isEnabled) { + bar.setProgress(-minEQLevel); + } + } - bassBar.setEnabled(isEnabled); - if (loudnessBar != null) { - loudnessBar.setEnabled(isEnabled); - } - if (changedEnabled && !isEnabled) { - bass.setStrength((short) 0); - bassBar.setProgress(0); - if (loudnessBar != null) { - loudnessEnhancer.setGain(0); - loudnessBar.setProgress(0); - } - } + bassBar.setEnabled(isEnabled); + if (loudnessBar != null) { + loudnessBar.setEnabled(isEnabled); + } + if (changedEnabled && !isEnabled) { + bass.setStrength((short) 0); + bassBar.setProgress(0); + if (loudnessBar != null) { + loudnessEnhancer.setGain(0); + loudnessBar.setProgress(0); + } + } - if (!isEnabled) { - masterLevel = 0; - SharedPreferences prefs = Util.getPreferences(context); - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt(Constants.PREFERENCES_EQUALIZER_SETTINGS, masterLevel); - editor.apply(); - } - } catch(Exception e) { - Log.e(TAG, "Failed to update bars"); - } - } + if (!isEnabled) { + masterLevel = 0; + SharedPreferences prefs = Util.getPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + editor.putInt(Constants.PREFERENCES_EQUALIZER_SETTINGS, masterLevel); + editor.apply(); + } + } catch(Exception e) { + Log.e(TAG, "Failed to update bars"); + } + } - private void initEqualizer() { - LinearLayout layout = (LinearLayout) rootView.findViewById(R.id.equalizer_layout); + private void initEqualizer() { + LinearLayout layout = (LinearLayout) rootView.findViewById(R.id.equalizer_layout); - final short minEQLevel = equalizer.getBandLevelRange()[0]; - final short maxEQLevel = equalizer.getBandLevelRange()[1]; + final short minEQLevel = equalizer.getBandLevelRange()[0]; + final short maxEQLevel = equalizer.getBandLevelRange()[1]; - // Setup Pregain - SharedPreferences prefs = Util.getPreferences(context); - masterLevel = (short)prefs.getInt(Constants.PREFERENCES_EQUALIZER_SETTINGS, 0); - initPregain(layout, minEQLevel, maxEQLevel); + // Setup Pregain + SharedPreferences prefs = Util.getPreferences(context); + masterLevel = (short)prefs.getInt(Constants.PREFERENCES_EQUALIZER_SETTINGS, 0); + initPregain(layout, minEQLevel, maxEQLevel); - for (short i = 0; i < equalizer.getNumberOfBands(); i++) { - final short band = i; + for (short i = 0; i < equalizer.getNumberOfBands(); i++) { + final short band = i; - View bandBar = LayoutInflater.from(context).inflate(R.layout.equalizer_bar, null); - TextView freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency); - final TextView levelTextView = (TextView) bandBar.findViewById(R.id.equalizer_level); - SeekBar bar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar); + View bandBar = LayoutInflater.from(context).inflate(R.layout.equalizer_bar, null); + TextView freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency); + final TextView levelTextView = (TextView) bandBar.findViewById(R.id.equalizer_level); + SeekBar bar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar); - freqTextView.setText((equalizer.getCenterFreq(band) / 1000) + " Hz"); + freqTextView.setText((equalizer.getCenterFreq(band) / 1000) + " Hz"); - bars.put(band, bar); - bar.setMax(maxEQLevel - minEQLevel); - short level = equalizer.getBandLevel(band); - if(equalizer.getEnabled()) { - level = (short) (level - masterLevel); - } - bar.setProgress(level - minEQLevel); - bar.setEnabled(equalizer.getEnabled()); - updateLevelText(levelTextView, level); + bars.put(band, bar); + bar.setMax(maxEQLevel - minEQLevel); + short level = equalizer.getBandLevel(band); + if(equalizer.getEnabled()) { + level = (short) (level - masterLevel); + } + bar.setProgress(level - minEQLevel); + bar.setEnabled(equalizer.getEnabled()); + updateLevelText(levelTextView, level); - bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - try { - short level = (short) (progress + minEQLevel); - if (fromUser) { - equalizer.setBandLevel(band, (short) (level + masterLevel)); - } - updateLevelText(levelTextView, level); - } catch(Exception e) { - Log.e(TAG, "Failed to change equalizer", e); - } - } + bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + try { + short level = (short) (progress + minEQLevel); + if (fromUser) { + equalizer.setBandLevel(band, (short) (level + masterLevel)); + } + updateLevelText(levelTextView, level); + } catch(Exception e) { + Log.e(TAG, "Failed to change equalizer", e); + } + } - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - layout.addView(bandBar); - } + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + layout.addView(bandBar); + } - LinearLayout specialLayout = (LinearLayout) rootView.findViewById(R.id.special_effects_layout); + LinearLayout specialLayout = (LinearLayout) rootView.findViewById(R.id.special_effects_layout); - // Setup bass booster - View bandBar = LayoutInflater.from(context).inflate(R.layout.equalizer_bar, null); - TextView freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency); - final TextView bassTextView = (TextView) bandBar.findViewById(R.id.equalizer_level); - bassBar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar); + // Setup bass booster + View bandBar = LayoutInflater.from(context).inflate(R.layout.equalizer_bar, null); + TextView freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency); + final TextView bassTextView = (TextView) bandBar.findViewById(R.id.equalizer_level); + bassBar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar); - freqTextView.setText(R.string.equalizer_bass_booster); - bassBar.setEnabled(equalizer.getEnabled()); - short bassLevel = 0; - if(bass.getEnabled()) { - bassLevel = bass.getRoundedStrength(); - } - bassTextView.setText(context.getResources().getString(R.string.equalizer_bass_size, bassLevel)); - bassBar.setMax(1000); - bassBar.setProgress(bassLevel); - bassBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - try { - bassTextView.setText(context.getResources().getString(R.string.equalizer_bass_size, progress)); - if (fromUser) { - if (progress > 0) { - if (!bass.getEnabled()) { - bass.setEnabled(true); - } - bass.setStrength((short) progress); - } else if (progress == 0 && bass.getEnabled()) { - bass.setStrength((short) progress); - bass.setEnabled(false); - } - } - } catch(Exception e) { - Log.w(TAG, "Error on changing bass: ", e); - } - } + freqTextView.setText(R.string.equalizer_bass_booster); + bassBar.setEnabled(equalizer.getEnabled()); + short bassLevel = 0; + if(bass.getEnabled()) { + bassLevel = bass.getRoundedStrength(); + } + bassTextView.setText(context.getResources().getString(R.string.equalizer_bass_size, bassLevel)); + bassBar.setMax(1000); + bassBar.setProgress(bassLevel); + bassBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + try { + bassTextView.setText(context.getResources().getString(R.string.equalizer_bass_size, progress)); + if (fromUser) { + if (progress > 0) { + if (!bass.getEnabled()) { + bass.setEnabled(true); + } + bass.setStrength((short) progress); + } else if (progress == 0 && bass.getEnabled()) { + bass.setStrength((short) progress); + bass.setEnabled(false); + } + } + } catch(Exception e) { + Log.w(TAG, "Error on changing bass: ", e); + } + } - @Override - public void onStartTrackingTouch(SeekBar seekBar) { + @Override + public void onStartTrackingTouch(SeekBar seekBar) { - } + } - @Override - public void onStopTrackingTouch(SeekBar seekBar) { + @Override + public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - specialLayout.addView(bandBar); + } + }); + specialLayout.addView(bandBar); - if(loudnessEnhancer != null && loudnessEnhancer.isAvailable()) { - // Setup loudness enhancer - bandBar = LayoutInflater.from(context).inflate(R.layout.equalizer_bar, null); - freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency); - final TextView loudnessTextView = (TextView) bandBar.findViewById(R.id.equalizer_level); - loudnessBar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar); + if(loudnessEnhancer != null && loudnessEnhancer.isAvailable()) { + // Setup loudness enhancer + bandBar = LayoutInflater.from(context).inflate(R.layout.equalizer_bar, null); + freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency); + final TextView loudnessTextView = (TextView) bandBar.findViewById(R.id.equalizer_level); + loudnessBar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar); - freqTextView.setText(R.string.equalizer_voice_booster); - loudnessBar.setEnabled(equalizer.getEnabled()); - int loudnessLevel = 0; - if(loudnessEnhancer.isEnabled()) { - loudnessLevel = (int) loudnessEnhancer.getGain(); - } - loudnessBar.setProgress(loudnessLevel / 100); - loudnessTextView.setText(context.getResources().getString(R.string.equalizer_db_size, loudnessLevel / 100)); - loudnessBar.setMax(15); - loudnessBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - try { - loudnessTextView.setText(context.getResources().getString(R.string.equalizer_db_size, progress)); - if(fromUser) { - if(progress > 0) { - if(!loudnessEnhancer.isEnabled()) { - loudnessEnhancer.enable(); - } - loudnessEnhancer.setGain(progress * 100); - } else if(progress == 0 && loudnessEnhancer.isEnabled()) { - loudnessEnhancer.setGain(progress * 100); - loudnessEnhancer.disable(); - } - } - } catch(Exception e) { - Log.w(TAG, "Error on changing loudness: ", e); - } - } + freqTextView.setText(R.string.equalizer_voice_booster); + loudnessBar.setEnabled(equalizer.getEnabled()); + int loudnessLevel = 0; + if(loudnessEnhancer.isEnabled()) { + loudnessLevel = (int) loudnessEnhancer.getGain(); + } + loudnessBar.setProgress(loudnessLevel / 100); + loudnessTextView.setText(context.getResources().getString(R.string.equalizer_db_size, loudnessLevel / 100)); + loudnessBar.setMax(15); + loudnessBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + try { + loudnessTextView.setText(context.getResources().getString(R.string.equalizer_db_size, progress)); + if(fromUser) { + if(progress > 0) { + if(!loudnessEnhancer.isEnabled()) { + loudnessEnhancer.enable(); + } + loudnessEnhancer.setGain(progress * 100); + } else if(progress == 0 && loudnessEnhancer.isEnabled()) { + loudnessEnhancer.setGain(progress * 100); + loudnessEnhancer.disable(); + } + } + } catch(Exception e) { + Log.w(TAG, "Error on changing loudness: ", e); + } + } - @Override - public void onStartTrackingTouch(SeekBar seekBar) { + @Override + public void onStartTrackingTouch(SeekBar seekBar) { - } + } - @Override - public void onStopTrackingTouch(SeekBar seekBar) { + @Override + public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - specialLayout.addView(bandBar); - } - } + } + }); + specialLayout.addView(bandBar); + } + } - private void initPregain(LinearLayout layout, final short minEQLevel, final short maxEQLevel) { - View bandBar = LayoutInflater.from(context).inflate(R.layout.equalizer_bar, null); - TextView freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency); - final TextView levelTextView = (TextView) bandBar.findViewById(R.id.equalizer_level); - SeekBar bar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar); + private void initPregain(LinearLayout layout, final short minEQLevel, final short maxEQLevel) { + View bandBar = LayoutInflater.from(context).inflate(R.layout.equalizer_bar, null); + TextView freqTextView = (TextView) bandBar.findViewById(R.id.equalizer_frequency); + final TextView levelTextView = (TextView) bandBar.findViewById(R.id.equalizer_level); + SeekBar bar = (SeekBar) bandBar.findViewById(R.id.equalizer_bar); - freqTextView.setText("Master"); + freqTextView.setText("Master"); - bars.put((short)-1, bar); - bar.setMax(maxEQLevel - minEQLevel); - bar.setProgress(masterLevel - minEQLevel); - bar.setEnabled(equalizer.getEnabled()); - updateLevelText(levelTextView, masterLevel); + bars.put((short)-1, bar); + bar.setMax(maxEQLevel - minEQLevel); + bar.setProgress(masterLevel - minEQLevel); + bar.setEnabled(equalizer.getEnabled()); + updateLevelText(levelTextView, masterLevel); - bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - try { - masterLevel = (short) (progress + minEQLevel); - if (fromUser) { - SharedPreferences prefs = Util.getPreferences(context); - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt(Constants.PREFERENCES_EQUALIZER_SETTINGS, masterLevel); - editor.apply(); - for (short i = 0; i < equalizer.getNumberOfBands(); i++) { - short level = (short) ((bars.get(i).getProgress() + minEQLevel) + masterLevel); - equalizer.setBandLevel(i, level); - } - } - updateLevelText(levelTextView, masterLevel); - } catch(Exception e) { - Log.e(TAG, "Failed to change equalizer", e); - } - } + bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + try { + masterLevel = (short) (progress + minEQLevel); + if (fromUser) { + SharedPreferences prefs = Util.getPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + editor.putInt(Constants.PREFERENCES_EQUALIZER_SETTINGS, masterLevel); + editor.apply(); + for (short i = 0; i < equalizer.getNumberOfBands(); i++) { + short level = (short) ((bars.get(i).getProgress() + minEQLevel) + masterLevel); + equalizer.setBandLevel(i, level); + } + } + updateLevelText(levelTextView, masterLevel); + } catch(Exception e) { + Log.e(TAG, "Failed to change equalizer", e); + } + } - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - } + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - } - }); - layout.addView(bandBar); - } + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + layout.addView(bandBar); + } - private void updateLevelText(TextView levelTextView, short level) { - levelTextView.setText((level > 0 ? "+" : "") + context.getResources().getString(R.string.equalizer_db_size, level / 100)); - } + private void updateLevelText(TextView levelTextView, short level) { + levelTextView.setText((level > 0 ? "+" : "") + context.getResources().getString(R.string.equalizer_db_size, level / 100)); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/MainFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/MainFragment.java index b2ba6d0..8fead61 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/MainFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/MainFragment.java @@ -42,179 +42,179 @@ import java.util.Arrays; import java.util.List; public class MainFragment extends SelectRecyclerFragment { - private static final String TAG = MainFragment.class.getSimpleName(); - public static final String SONGS_LIST_PREFIX = "songs-"; - public static final String SONGS_NEWEST = SONGS_LIST_PREFIX + "newest"; - public static final String SONGS_TOP_PLAYED = SONGS_LIST_PREFIX + "topPlayed"; - public static final String SONGS_RECENT = SONGS_LIST_PREFIX + "recent"; - public static final String SONGS_FREQUENT = SONGS_LIST_PREFIX + "frequent"; + private static final String TAG = MainFragment.class.getSimpleName(); + public static final String SONGS_LIST_PREFIX = "songs-"; + public static final String SONGS_NEWEST = SONGS_LIST_PREFIX + "newest"; + public static final String SONGS_TOP_PLAYED = SONGS_LIST_PREFIX + "topPlayed"; + public static final String SONGS_RECENT = SONGS_LIST_PREFIX + "recent"; + public static final String SONGS_FREQUENT = SONGS_LIST_PREFIX + "frequent"; - public MainFragment() { - super(); - pullToRefresh = false; - serialize = false; - backgroundUpdate = false; - alwaysFullscreen = true; - } + public MainFragment() { + super(); + pullToRefresh = false; + serialize = false; + backgroundUpdate = false; + alwaysFullscreen = true; + } - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { - menuInflater.inflate(R.menu.main, menu); - onFinishSetupOptionsMenu(menu); - } + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { + menuInflater.inflate(R.menu.main, menu); + onFinishSetupOptionsMenu(menu); + } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if(super.onOptionsItemSelected(item)) { - return true; - } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if(super.onOptionsItemSelected(item)) { + return true; + } - return false; - } + return false; + } - @Override - public int getOptionsMenu() { - return 0; - } + @Override + public int getOptionsMenu() { + return 0; + } - @Override - public SectionAdapter getAdapter(List objs) { - List> sections = new ArrayList<>(); - List headers = new ArrayList<>(); + @Override + public SectionAdapter getAdapter(List objs) { + List> sections = new ArrayList<>(); + List headers = new ArrayList<>(); - List albums = new ArrayList<>(); - albums.add(R.string.main_albums_random); + List albums = new ArrayList<>(); + albums.add(R.string.main_albums_random); albums.add(R.string.main_albums_alphabetical); - albums.add(R.string.main_albums_genres); - albums.add(R.string.main_albums_year); - albums.add(R.string.main_albums_recent); - albums.add(R.string.main_albums_frequent); + albums.add(R.string.main_albums_genres); + albums.add(R.string.main_albums_year); + albums.add(R.string.main_albums_recent); + albums.add(R.string.main_albums_frequent); - sections.add(albums); - headers.add("albums"); + sections.add(albums); + headers.add("albums"); - return new MainAdapter(context, headers, sections, this); - } + return new MainAdapter(context, headers, sections, this); + } - @Override - public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { - return Arrays.asList(0); - } + @Override + public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { + return Arrays.asList(0); + } - @Override - public int getTitleResource() { - return R.string.common_appname; - } + @Override + public int getTitleResource() { + return R.string.common_appname; + } - private void showAlbumList(String type) { - if("genres".equals(type)) { - SubsonicFragment fragment = new SelectGenreFragment(); - replaceFragment(fragment); - } else if("years".equals(type)) { - SubsonicFragment fragment = new SelectYearFragment(); - replaceFragment(fragment); - } else { - // Clear out recently added count when viewing - if("newest".equals(type)) { - SharedPreferences.Editor editor = Util.getPreferences(context).edit(); - editor.putInt(Constants.PREFERENCES_KEY_RECENT_COUNT + Util.getActiveServer(context), 0); - editor.apply(); - } - - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, type); - args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20); - args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0); - fragment.setArguments(args); + private void showAlbumList(String type) { + if("genres".equals(type)) { + SubsonicFragment fragment = new SelectGenreFragment(); + replaceFragment(fragment); + } else if("years".equals(type)) { + SubsonicFragment fragment = new SelectYearFragment(); + replaceFragment(fragment); + } else { + // Clear out recently added count when viewing + if("newest".equals(type)) { + SharedPreferences.Editor editor = Util.getPreferences(context).edit(); + editor.putInt(Constants.PREFERENCES_KEY_RECENT_COUNT + Util.getActiveServer(context), 0); + editor.apply(); + } - replaceFragment(fragment); - } - } + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, type); + args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20); + args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0); + fragment.setArguments(args); - private void showAboutDialog() { - new LoadingTask(context) { - Long[] used; - long bytesTotalFs; - long bytesAvailableFs; + replaceFragment(fragment); + } + } - @Override - protected Void doInBackground() throws Throwable { - File rootFolder = FileUtil.getMusicDirectory(context); - StatFs stat = new StatFs(rootFolder.getPath()); - bytesTotalFs = (long) stat.getBlockCount() * (long) stat.getBlockSize(); - bytesAvailableFs = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); + private void showAboutDialog() { + new LoadingTask(context) { + Long[] used; + long bytesTotalFs; + long bytesAvailableFs; - used = FileUtil.getUsedSize(context, rootFolder); - return null; - } + @Override + protected Void doInBackground() throws Throwable { + File rootFolder = FileUtil.getMusicDirectory(context); + StatFs stat = new StatFs(rootFolder.getPath()); + bytesTotalFs = (long) stat.getBlockCount() * (long) stat.getBlockSize(); + bytesAvailableFs = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); - @Override - protected void done(Void result) { - List headers = new ArrayList<>(); - List details = new ArrayList<>(); + used = FileUtil.getUsedSize(context, rootFolder); + return null; + } - headers.add(R.string.details_author); - details.add("Andrew Rabert"); + @Override + protected void done(Void result) { + List headers = new ArrayList<>(); + List details = new ArrayList<>(); - headers.add(R.string.details_email); - details.add("ar@nullsum.net"); + headers.add(R.string.details_author); + details.add("Andrew Rabert"); - try { - headers.add(R.string.details_version); - details.add(context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName); - } catch(Exception e) { - details.add(""); - } + headers.add(R.string.details_email); + details.add("ar@nullsum.net"); - Resources res = context.getResources(); - headers.add(R.string.details_files_cached); - details.add(Long.toString(used[0])); + try { + headers.add(R.string.details_version); + details.add(context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName); + } catch(Exception e) { + details.add(""); + } - headers.add(R.string.details_files_permanent); - details.add(Long.toString(used[1])); + Resources res = context.getResources(); + headers.add(R.string.details_files_cached); + details.add(Long.toString(used[0])); - headers.add(R.string.details_used_space); - details.add(res.getString(R.string.details_of, Util.formatLocalizedBytes(used[2], context), Util.formatLocalizedBytes(Util.getCacheSizeMB(context) * 1024L * 1024L, context))); + headers.add(R.string.details_files_permanent); + details.add(Long.toString(used[1])); - headers.add(R.string.details_available_space); - details.add(res.getString(R.string.details_of, Util.formatLocalizedBytes(bytesAvailableFs, context), Util.formatLocalizedBytes(bytesTotalFs, context))); + headers.add(R.string.details_used_space); + details.add(res.getString(R.string.details_of, Util.formatLocalizedBytes(used[2], context), Util.formatLocalizedBytes(Util.getCacheSizeMB(context) * 1024L * 1024L, context))); - Util.showDetailsDialog(context, R.string.main_about_title, headers, details); - } - }.execute(); - } + headers.add(R.string.details_available_space); + details.add(res.getString(R.string.details_of, Util.formatLocalizedBytes(bytesAvailableFs, context), Util.formatLocalizedBytes(bytesTotalFs, context))); - @Override - public void onItemClicked(UpdateView updateView, Integer item) { - if (item == R.string.main_albums_random) { - showAlbumList("random"); - } else if (item == R.string.main_albums_recent) { - showAlbumList("recent"); - } else if (item == R.string.main_albums_frequent) { - showAlbumList("frequent"); - } else if(item == R.string.main_albums_genres) { - showAlbumList("genres"); - } else if(item == R.string.main_albums_year) { - showAlbumList("years"); - } else if(item == R.string.main_albums_alphabetical) { - showAlbumList("alphabeticalByName"); - } else if (item == R.string.main_songs_newest) { - showAlbumList(SONGS_NEWEST); - } else if (item == R.string.main_songs_top_played) { - showAlbumList(SONGS_TOP_PLAYED); - } else if (item == R.string.main_songs_recent) { - showAlbumList(SONGS_RECENT); - } else if (item == R.string.main_songs_frequent) { - showAlbumList(SONGS_FREQUENT); - } - } + Util.showDetailsDialog(context, R.string.main_about_title, headers, details); + } + }.execute(); + } - @Override - public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Integer item) {} + @Override + public void onItemClicked(UpdateView updateView, Integer item) { + if (item == R.string.main_albums_random) { + showAlbumList("random"); + } else if (item == R.string.main_albums_recent) { + showAlbumList("recent"); + } else if (item == R.string.main_albums_frequent) { + showAlbumList("frequent"); + } else if(item == R.string.main_albums_genres) { + showAlbumList("genres"); + } else if(item == R.string.main_albums_year) { + showAlbumList("years"); + } else if(item == R.string.main_albums_alphabetical) { + showAlbumList("alphabeticalByName"); + } else if (item == R.string.main_songs_newest) { + showAlbumList(SONGS_NEWEST); + } else if (item == R.string.main_songs_top_played) { + showAlbumList(SONGS_TOP_PLAYED); + } else if (item == R.string.main_songs_recent) { + showAlbumList(SONGS_RECENT); + } else if (item == R.string.main_songs_frequent) { + showAlbumList(SONGS_FREQUENT); + } + } - @Override - public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Integer item) { - return false; - } + @Override + public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Integer item) {} + + @Override + public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Integer item) { + return false; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/NowPlayingFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/NowPlayingFragment.java index 6e3c6b9..12ccaa4 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/NowPlayingFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/NowPlayingFragment.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.fragments; @@ -81,830 +81,830 @@ import java.util.ArrayList; import java.util.concurrent.ScheduledFuture; public class NowPlayingFragment extends SubsonicFragment implements OnGestureListener, SectionAdapter.OnItemClickedListener, OnSongChangedListener { - private static final String TAG = NowPlayingFragment.class.getSimpleName(); - private static final int PERCENTAGE_OF_SCREEN_FOR_SWIPE = 10; - - private static final int ACTION_PREVIOUS = 1; - private static final int ACTION_NEXT = 2; - private static final int ACTION_REWIND = 3; - private static final int ACTION_FORWARD = 4; - - private ViewFlipper playlistFlipper; - private TextView emptyTextView; - private TextView songTitleTextView; - private ImageView albumArtImageView; - private RecyclerView playlistView; - private TextView positionTextView; - private TextView durationTextView; - private TextView statusTextView; - private SeekBar progressBar; - private AutoRepeatButton previousButton; - private AutoRepeatButton nextButton; - private AutoRepeatButton rewindButton; - private AutoRepeatButton fastforwardButton; - private View pauseButton; - private View stopButton; - private View startButton; - private ImageButton repeatButton; - private View toggleListButton; - - private ScheduledExecutorService executorService; - private DownloadFile currentPlaying; - private int swipeDistance; - private int swipeVelocity; - private ScheduledFuture hideControlsFuture; - private List songList; - private DownloadFileAdapter songListAdapter; - private boolean seekInProgress = false; - private boolean startFlipped = false; - private boolean scrollWhenLoaded = false; - private int lastY = 0; - private int currentPlayingSize = 0; - - /** - * Called when the activity is first created. - */ - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - if(savedInstanceState != null) { - if(savedInstanceState.getInt(Constants.FRAGMENT_DOWNLOAD_FLIPPER) == 1) { - startFlipped = true; - } - } - primaryFragment = false; - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putInt(Constants.FRAGMENT_DOWNLOAD_FLIPPER, playlistFlipper.getDisplayedChild()); - } - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - rootView = inflater.inflate(R.layout.download, container, false); - setTitle(R.string.button_bar_now_playing); - - WindowManager w = context.getWindowManager(); - Display d = w.getDefaultDisplay(); - swipeDistance = (d.getWidth() + d.getHeight()) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100; - swipeVelocity = (d.getWidth() + d.getHeight()) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100; - gestureScanner = new GestureDetector(this); - - playlistFlipper = (ViewFlipper)rootView.findViewById(R.id.download_playlist_flipper); - emptyTextView = (TextView)rootView.findViewById(R.id.download_empty); - songTitleTextView = (TextView)rootView.findViewById(R.id.download_song_title); - albumArtImageView = (ImageView)rootView.findViewById(R.id.download_album_art_image); - positionTextView = (TextView)rootView.findViewById(R.id.download_position); - durationTextView = (TextView)rootView.findViewById(R.id.download_duration); - statusTextView = (TextView)rootView.findViewById(R.id.download_status); - progressBar = (SeekBar)rootView.findViewById(R.id.download_progress_bar); - previousButton = (AutoRepeatButton)rootView.findViewById(R.id.download_previous); - nextButton = (AutoRepeatButton)rootView.findViewById(R.id.download_next); - rewindButton = (AutoRepeatButton) rootView.findViewById(R.id.download_rewind); - fastforwardButton = (AutoRepeatButton) rootView.findViewById(R.id.download_fastforward); - pauseButton =rootView.findViewById(R.id.download_pause); - stopButton =rootView.findViewById(R.id.download_stop); - startButton =rootView.findViewById(R.id.download_start); - repeatButton = (ImageButton)rootView.findViewById(R.id.download_repeat); - toggleListButton =rootView.findViewById(R.id.download_toggle_list); - - playlistView = (RecyclerView)rootView.findViewById(R.id.download_list); - FastScroller fastScroller = (FastScroller) rootView.findViewById(R.id.download_fast_scroller); - fastScroller.attachRecyclerView(playlistView); - setupLayoutManager(playlistView, false); - ItemTouchHelper touchHelper = new ItemTouchHelper(new DownloadFileItemHelperCallback(this, true)); - touchHelper.attachToRecyclerView(playlistView); - - View.OnTouchListener touchListener = new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent me) { - return gestureScanner.onTouchEvent(me); - } - }; - pauseButton.setOnTouchListener(touchListener); - stopButton.setOnTouchListener(touchListener); - startButton.setOnTouchListener(touchListener); - emptyTextView.setOnTouchListener(touchListener); - albumArtImageView.setOnTouchListener(new View.OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent me) { - if (me.getAction() == MotionEvent.ACTION_DOWN) { - lastY = (int) me.getRawY(); - } - return gestureScanner.onTouchEvent(me); - } - }); - - previousButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - warnIfStorageUnavailable(); - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - getDownloadService().previous(); - return null; - } - }.execute(); - setControlsVisible(true); - } - }); - previousButton.setOnRepeatListener(new Runnable() { - public void run() { - changeProgress(true); - } - }); - - nextButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - warnIfStorageUnavailable(); - new SilentBackgroundTask(context) { - @Override - protected Boolean doInBackground() throws Throwable { - getDownloadService().next(); - return true; - } - }.execute(); - setControlsVisible(true); - } - }); - nextButton.setOnRepeatListener(new Runnable() { - public void run() { - changeProgress(false); - } - }); - - rewindButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - changeProgress(true); - } - }); - rewindButton.setOnRepeatListener(new Runnable() { - public void run() { - changeProgress(true); - } - }); - - fastforwardButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - changeProgress(false); - } - }); - fastforwardButton.setOnRepeatListener(new Runnable() { - public void run() { - changeProgress(false); - } - }); - - - pauseButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - getDownloadService().pause(); - return null; - } - }.execute(); - } - }); - - stopButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - getDownloadService().reset(); - return null; - } - }.execute(); - } - }); - - startButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - warnIfStorageUnavailable(); - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - start(); - return null; - } - }.execute(); - } - }); - - repeatButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - RepeatMode repeatMode = getDownloadService().getRepeatMode().next(); - getDownloadService().setRepeatMode(repeatMode); - switch (repeatMode) { - case OFF: - Util.toast(context, R.string.download_repeat_off); - break; - case ALL: - Util.toast(context, R.string.download_repeat_all); - break; - case SINGLE: - Util.toast(context, R.string.download_repeat_single); - break; - default: - break; - } - updateRepeatButton(); - setControlsVisible(true); - } - }); - - toggleListButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - toggleFullscreenAlbumArt(); - setControlsVisible(true); - } - }); - - View overlay = rootView.findViewById(R.id.download_overlay_buttons); - final int overlayHeight = overlay != null ? overlay.getHeight() : -1; - albumArtImageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (overlayHeight == -1 || lastY < (view.getBottom() - overlayHeight)) { - toggleFullscreenAlbumArt(); - setControlsVisible(true); - } - } - }); - - progressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onStopTrackingTouch(final SeekBar seekBar) { - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - getDownloadService().seekTo(progressBar.getProgress()); - return null; - } - - @Override - protected void done(Void result) { - seekInProgress = false; - } - }.execute(); - } - - @Override - public void onStartTrackingTouch(final SeekBar seekBar) { - seekInProgress = true; - } - - @Override - public void onProgressChanged(final SeekBar seekBar, final int position, final boolean fromUser) { - if (fromUser) { - positionTextView.setText(Util.formatDuration(position / 1000)); - setControlsVisible(true); - } - } - }); - - return rootView; - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { - DownloadService downloadService = getDownloadService(); - if(Util.isOffline(context)) { - menuInflater.inflate(R.menu.nowplaying_offline, menu); - } else { - menuInflater.inflate(R.menu.nowplaying, menu); - } - if(downloadService != null && downloadService.isRemovePlayed()) { - menu.findItem(R.id.menu_remove_played).setChecked(true); - } - - if(downloadService != null) { - SharedPreferences prefs = Util.getPreferences(context); - boolean equalizerOn = prefs.getBoolean(Constants.PREFERENCES_EQUALIZER_ON, false); - if (equalizerOn && downloadService != null) { - if(downloadService.getEqualizerController() != null && downloadService.getEqualizerController().isEnabled()) { - menu.findItem(R.id.menu_equalizer).setChecked(true); - } - } - } else { - menu.removeItem(R.id.menu_equalizer); - } - - if(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_BATCH_MODE, false)) { - menu.findItem(R.id.menu_batch_mode).setChecked(true); - } - } - - @Override - public boolean onOptionsItemSelected(MenuItem menuItem) { - if(menuItemSelected(menuItem.getItemId(), null)) { - return true; - } - - return super.onOptionsItemSelected(menuItem); - } - - @Override - public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, DownloadFile downloadFile) { - if(Util.isOffline(context)) { - menuInflater.inflate(R.menu.nowplaying_context_offline, menu); - } else { - menuInflater.inflate(R.menu.nowplaying_context, menu); - } - - if (downloadFile.getSong().getParent() == null) { - menu.findItem(R.id.menu_show_album).setVisible(false); - menu.findItem(R.id.menu_show_artist).setVisible(false); - } - - MenuUtil.hideMenuItems(context, menu, updateView); - } - - @Override - public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, DownloadFile downloadFile) { - if(onContextItemSelected(menuItem, downloadFile.getSong())) { - return true; - } - - return menuItemSelected(menuItem.getItemId(), downloadFile); - } - - private boolean menuItemSelected(int menuItemId, final DownloadFile song) { - List songs; - switch (menuItemId) { - case R.id.menu_show_album: case R.id.menu_show_artist: - Entry entry = song.getSong(); - - Intent intent = new Intent(context, SubsonicFragmentActivity.class); - intent.putExtra(Constants.INTENT_EXTRA_VIEW_ALBUM, true); - String albumId; - String albumName; - if(menuItemId == R.id.menu_show_album) { - if(Util.isTagBrowsing(context)) { - albumId = entry.getAlbumId(); - } else { - albumId = entry.getParent(); - } - albumName = entry.getAlbum(); - } else { - if(Util.isTagBrowsing(context)) { - albumId = entry.getArtistId(); - } else { - albumId = entry.getGrandParent(); - if(albumId == null) { - intent.putExtra(Constants.INTENT_EXTRA_NAME_CHILD_ID, entry.getParent()); - } - } - albumName = entry.getArtist(); - intent.putExtra(Constants.INTENT_EXTRA_NAME_ARTIST, true); - } - intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, albumId); - intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, albumName); - intent.putExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE, "Artist"); - - if(Util.isOffline(context)) { - try { - // This should only be successful if this is a online song in offline mode - Integer.parseInt(entry.getParent()); - String root = FileUtil.getMusicDirectory(context).getPath(); - String id = root + "/" + entry.getPath(); - id = id.substring(0, id.lastIndexOf("/")); - if(menuItemId == R.id.menu_show_album) { - intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, id); - } - id = id.substring(0, id.lastIndexOf("/")); - if(menuItemId != R.id.menu_show_album) { - intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, id); - intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, entry.getArtist()); - intent.removeExtra(Constants.INTENT_EXTRA_NAME_CHILD_ID); - } - } catch(Exception e) { - // Do nothing, entry.getParent() is fine - } - } - - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - Util.startActivityWithoutTransition(context, intent); - return true; - case R.id.menu_remove_all: - Util.confirmDialog(context, R.string.download_menu_remove_all, "", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - getDownloadService().setShufflePlayEnabled(false); - getDownloadService().clear(); - return null; - } - - @Override - protected void done(Void result) { - context.closeNowPlaying(); - } - }.execute(); - } - }); - return true; - case R.id.menu_remove_played: - if (getDownloadService().isRemovePlayed()) { - getDownloadService().setRemovePlayed(false); - } else { - getDownloadService().setRemovePlayed(true); - } - context.supportInvalidateOptionsMenu(); - return true; - case R.id.menu_shuffle: - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - getDownloadService().shuffle(); - return null; - } - - @Override - protected void done(Void result) { - Util.toast(context, R.string.download_menu_shuffle_notification); - } - }.execute(); - return true; - case R.id.menu_save_playlist: - List entries = new LinkedList(); - for (DownloadFile downloadFile : getDownloadService().getSongs()) { - entries.add(downloadFile.getSong()); - } - createNewPlaylist(entries, true); - return true; - case R.id.menu_info: - displaySongInfo(song.getSong()); - return true; - case R.id.menu_equalizer: { - DownloadService downloadService = getDownloadService(); - if (downloadService != null) { - EqualizerController controller = downloadService.getEqualizerController(); - if(controller != null) { - SubsonicFragment fragment = new EqualizerFragment(); - replaceFragment(fragment); - setControlsVisible(true); - - return true; - } - } - - // Any failed condition will get here - Util.toast(context, "Failed to start equalizer. Try restarting."); - return true; - }case R.id.menu_batch_mode: - if(Util.isBatchMode(context)) { - Util.setBatchMode(context, false); - songListAdapter.notifyDataSetChanged(); - } else { - Util.setBatchMode(context, true); - songListAdapter.notifyDataSetChanged(); - } - context.supportInvalidateOptionsMenu(); - - return true; - default: - return false; - } - } - - @Override - public void onResume() { - super.onResume(); - if(this.primaryFragment) { - onResumeHandlers(); - } else { - update(); - } - } - private void onResumeHandlers() { - executorService = Executors.newSingleThreadScheduledExecutor(); - setControlsVisible(true); - - final DownloadService downloadService = getDownloadService(); - if (downloadService == null || downloadService.getCurrentPlaying() == null || startFlipped) { - playlistFlipper.setDisplayedChild(1); - startFlipped = false; - } - - updateButtons(); - - if(currentPlaying == null && downloadService != null && currentPlaying == downloadService.getCurrentPlaying()) { - getImageLoader().loadImage(albumArtImageView, (Entry) null, true, false); - } - - context.runWhenServiceAvailable(new Runnable() { - @Override - public void run() { - if (primaryFragment) { - DownloadService downloadService = getDownloadService(); - downloadService.addOnSongChangedListener(NowPlayingFragment.this, true); - } - updateRepeatButton(); - updateTitle(); - } - }); - } - - @Override - public void onPause() { - super.onPause(); - onPauseHandlers(); - } - private void onPauseHandlers() { - if(executorService != null) { - DownloadService downloadService = getDownloadService(); - if (downloadService != null) { - downloadService.removeOnSongChangeListener(this); - } - playlistFlipper.setDisplayedChild(0); - } - } - - @Override - public void setPrimaryFragment(boolean primary) { - super.setPrimaryFragment(primary); - if(rootView != null) { - if(primary) { - onResumeHandlers(); - } else { - onPauseHandlers(); - } - } - } - - @Override - public void setTitle(int title) { - this.title = context.getResources().getString(title); - if(this.primaryFragment) { - context.setTitle(this.title); - } - } - @Override - public void setSubtitle(CharSequence title) { - this.subtitle = title; - if(this.primaryFragment) { - context.setSubtitle(title); - } - } - - @Override - public SectionAdapter getCurrentAdapter() { - return songListAdapter; - } - - private void scheduleHideControls() { - if (hideControlsFuture != null) { - hideControlsFuture.cancel(false); - } - - final Handler handler = new Handler(); - Runnable runnable = new Runnable() { - @Override - public void run() { - handler.post(new Runnable() { - @Override - public void run() { - setControlsVisible(false); - } - }); - } - }; - hideControlsFuture = executorService.schedule(runnable, 3000L, TimeUnit.MILLISECONDS); - } - - private void setControlsVisible(boolean visible) { - DownloadService downloadService = getDownloadService(); - try { - long duration = 1700L; - FadeOutAnimation.createAndStart(rootView.findViewById(R.id.download_overlay_buttons), !visible, duration); - - if (visible) { - scheduleHideControls(); - } - } catch(Exception e) { - - } - } - - private void updateButtons() { - if(context == null) { - return; - } - } - - // Scroll to current playing/downloading. - private void scrollToCurrent() { - if (getDownloadService() == null || songListAdapter == null) { - scrollWhenLoaded = true; - return; - } - - // Try to get position of current playing/downloading - int position = songListAdapter.getItemPosition(currentPlaying); - if(position == -1) { - DownloadFile currentDownloading = getDownloadService().getCurrentDownloading(); - position = songListAdapter.getItemPosition(currentDownloading); - } - - // If found, scroll to it - if(position != -1) { - // RecyclerView.scrollToPosition just puts it on the screen (ie: bottom if scrolled below it) - LinearLayoutManager layoutManager = (LinearLayoutManager) playlistView.getLayoutManager(); - layoutManager.scrollToPositionWithOffset(position, 0); - } - } - - private void update() { - if(startFlipped) { - startFlipped = false; - scrollToCurrent(); - } - } - - private int getMinutes(int progress) { - if(progress < 30) { - return progress + 1; - } else if(progress < 49) { - return (progress - 30) * 5 + getMinutes(29); - } else if(progress < 57) { - return (progress - 48) * 30 + getMinutes(48); - } else if(progress < 81) { - return (progress - 56) * 60 + getMinutes(56); - } else { - return (progress - 80) * 150 + getMinutes(80); - } - } - - private void toggleFullscreenAlbumArt() { - if (playlistFlipper.getDisplayedChild() == 1) { - playlistFlipper.setInAnimation(AnimationUtils.loadAnimation(context, R.anim.push_down_in)); - playlistFlipper.setOutAnimation(AnimationUtils.loadAnimation(context, R.anim.push_down_out)); - playlistFlipper.setDisplayedChild(0); - } else { - scrollToCurrent(); - playlistFlipper.setInAnimation(AnimationUtils.loadAnimation(context, R.anim.push_up_in)); - playlistFlipper.setOutAnimation(AnimationUtils.loadAnimation(context, R.anim.push_up_out)); - playlistFlipper.setDisplayedChild(1); - - UpdateView.triggerUpdate(); - } - } - - private void start() { - DownloadService service = getDownloadService(); - PlayerState state = service.getPlayerState(); - if (state == PAUSED || state == COMPLETED || state == STOPPED) { - service.start(); - } else if (state == STOPPED || state == IDLE) { - warnIfStorageUnavailable(); - int current = service.getCurrentPlayingIndex(); - // TODO: Use play() method. - if (current == -1) { - service.play(0); - } else { - service.play(current); - } - } - } - - private void changeProgress(final boolean rewind) { - final DownloadService downloadService = getDownloadService(); - if(downloadService == null) { - return; - } - - new SilentBackgroundTask(context) { - int seekTo; - - @Override - protected Void doInBackground() throws Throwable { - if(rewind) { - seekTo = downloadService.rewind(); - } else { - seekTo = downloadService.fastForward(); - } - return null; - } - - @Override - protected void done(Void result) { - progressBar.setProgress(seekTo); - } - }.execute(); - } - - @Override - public boolean onDown(MotionEvent me) { - setControlsVisible(true); - return false; - } - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - final DownloadService downloadService = getDownloadService(); - if (downloadService == null || e1 == null || e2 == null) { - return false; - } - - // Right to Left swipe - int action = 0; - if (e1.getX() - e2.getX() > swipeDistance && Math.abs(velocityX) > swipeVelocity) { - action = ACTION_NEXT; - } - // Left to Right swipe - else if (e2.getX() - e1.getX() > swipeDistance && Math.abs(velocityX) > swipeVelocity) { - action = ACTION_PREVIOUS; - } - // Top to Bottom swipe - else if (e2.getY() - e1.getY() > swipeDistance && Math.abs(velocityY) > swipeVelocity) { - action = ACTION_FORWARD; - } - // Bottom to Top swipe - else if (e1.getY() - e2.getY() > swipeDistance && Math.abs(velocityY) > swipeVelocity) { - action = ACTION_REWIND; - } - - if(action > 0) { - final int performAction = action; - warnIfStorageUnavailable(); - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - switch(performAction) { - case ACTION_NEXT: - downloadService.next(); - break; - case ACTION_PREVIOUS: - downloadService.previous(); - break; - case ACTION_FORWARD: - downloadService.seekTo(downloadService.getPlayerPosition() + DownloadService.FAST_FORWARD); - break; - case ACTION_REWIND: - downloadService.seekTo(downloadService.getPlayerPosition() - DownloadService.REWIND); - break; - } - return null; - } - }.execute(); - - return true; - } else { - return false; - } - } - - @Override - public void onLongPress(MotionEvent e) { - } - - @Override - public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { - return false; - } - - @Override - public void onShowPress(MotionEvent e) { - } - - @Override - public boolean onSingleTapUp(MotionEvent e) { - return false; - } - - @Override - public void onItemClicked(UpdateView updateView, final DownloadFile item) { - warnIfStorageUnavailable(); - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - getDownloadService().play(item); - return null; - } - }.execute(); - } - - @Override - public void onSongChanged(DownloadFile currentPlaying, int currentPlayingIndex) { - this.currentPlaying = currentPlaying; - setupSubtitle(currentPlayingIndex); + private static final String TAG = NowPlayingFragment.class.getSimpleName(); + private static final int PERCENTAGE_OF_SCREEN_FOR_SWIPE = 10; + + private static final int ACTION_PREVIOUS = 1; + private static final int ACTION_NEXT = 2; + private static final int ACTION_REWIND = 3; + private static final int ACTION_FORWARD = 4; + + private ViewFlipper playlistFlipper; + private TextView emptyTextView; + private TextView songTitleTextView; + private ImageView albumArtImageView; + private RecyclerView playlistView; + private TextView positionTextView; + private TextView durationTextView; + private TextView statusTextView; + private SeekBar progressBar; + private AutoRepeatButton previousButton; + private AutoRepeatButton nextButton; + private AutoRepeatButton rewindButton; + private AutoRepeatButton fastforwardButton; + private View pauseButton; + private View stopButton; + private View startButton; + private ImageButton repeatButton; + private View toggleListButton; + + private ScheduledExecutorService executorService; + private DownloadFile currentPlaying; + private int swipeDistance; + private int swipeVelocity; + private ScheduledFuture hideControlsFuture; + private List songList; + private DownloadFileAdapter songListAdapter; + private boolean seekInProgress = false; + private boolean startFlipped = false; + private boolean scrollWhenLoaded = false; + private int lastY = 0; + private int currentPlayingSize = 0; + + /** + * Called when the activity is first created. + */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + if(savedInstanceState != null) { + if(savedInstanceState.getInt(Constants.FRAGMENT_DOWNLOAD_FLIPPER) == 1) { + startFlipped = true; + } + } + primaryFragment = false; + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putInt(Constants.FRAGMENT_DOWNLOAD_FLIPPER, playlistFlipper.getDisplayedChild()); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { + rootView = inflater.inflate(R.layout.download, container, false); + setTitle(R.string.button_bar_now_playing); + + WindowManager w = context.getWindowManager(); + Display d = w.getDefaultDisplay(); + swipeDistance = (d.getWidth() + d.getHeight()) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100; + swipeVelocity = (d.getWidth() + d.getHeight()) * PERCENTAGE_OF_SCREEN_FOR_SWIPE / 100; + gestureScanner = new GestureDetector(this); + + playlistFlipper = (ViewFlipper)rootView.findViewById(R.id.download_playlist_flipper); + emptyTextView = (TextView)rootView.findViewById(R.id.download_empty); + songTitleTextView = (TextView)rootView.findViewById(R.id.download_song_title); + albumArtImageView = (ImageView)rootView.findViewById(R.id.download_album_art_image); + positionTextView = (TextView)rootView.findViewById(R.id.download_position); + durationTextView = (TextView)rootView.findViewById(R.id.download_duration); + statusTextView = (TextView)rootView.findViewById(R.id.download_status); + progressBar = (SeekBar)rootView.findViewById(R.id.download_progress_bar); + previousButton = (AutoRepeatButton)rootView.findViewById(R.id.download_previous); + nextButton = (AutoRepeatButton)rootView.findViewById(R.id.download_next); + rewindButton = (AutoRepeatButton) rootView.findViewById(R.id.download_rewind); + fastforwardButton = (AutoRepeatButton) rootView.findViewById(R.id.download_fastforward); + pauseButton =rootView.findViewById(R.id.download_pause); + stopButton =rootView.findViewById(R.id.download_stop); + startButton =rootView.findViewById(R.id.download_start); + repeatButton = (ImageButton)rootView.findViewById(R.id.download_repeat); + toggleListButton =rootView.findViewById(R.id.download_toggle_list); + + playlistView = (RecyclerView)rootView.findViewById(R.id.download_list); + FastScroller fastScroller = (FastScroller) rootView.findViewById(R.id.download_fast_scroller); + fastScroller.attachRecyclerView(playlistView); + setupLayoutManager(playlistView, false); + ItemTouchHelper touchHelper = new ItemTouchHelper(new DownloadFileItemHelperCallback(this, true)); + touchHelper.attachToRecyclerView(playlistView); + + View.OnTouchListener touchListener = new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent me) { + return gestureScanner.onTouchEvent(me); + } + }; + pauseButton.setOnTouchListener(touchListener); + stopButton.setOnTouchListener(touchListener); + startButton.setOnTouchListener(touchListener); + emptyTextView.setOnTouchListener(touchListener); + albumArtImageView.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent me) { + if (me.getAction() == MotionEvent.ACTION_DOWN) { + lastY = (int) me.getRawY(); + } + return gestureScanner.onTouchEvent(me); + } + }); + + previousButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + warnIfStorageUnavailable(); + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + getDownloadService().previous(); + return null; + } + }.execute(); + setControlsVisible(true); + } + }); + previousButton.setOnRepeatListener(new Runnable() { + public void run() { + changeProgress(true); + } + }); + + nextButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + warnIfStorageUnavailable(); + new SilentBackgroundTask(context) { + @Override + protected Boolean doInBackground() throws Throwable { + getDownloadService().next(); + return true; + } + }.execute(); + setControlsVisible(true); + } + }); + nextButton.setOnRepeatListener(new Runnable() { + public void run() { + changeProgress(false); + } + }); + + rewindButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + changeProgress(true); + } + }); + rewindButton.setOnRepeatListener(new Runnable() { + public void run() { + changeProgress(true); + } + }); + + fastforwardButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + changeProgress(false); + } + }); + fastforwardButton.setOnRepeatListener(new Runnable() { + public void run() { + changeProgress(false); + } + }); + + + pauseButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + getDownloadService().pause(); + return null; + } + }.execute(); + } + }); + + stopButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + getDownloadService().reset(); + return null; + } + }.execute(); + } + }); + + startButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + warnIfStorageUnavailable(); + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + start(); + return null; + } + }.execute(); + } + }); + + repeatButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + RepeatMode repeatMode = getDownloadService().getRepeatMode().next(); + getDownloadService().setRepeatMode(repeatMode); + switch (repeatMode) { + case OFF: + Util.toast(context, R.string.download_repeat_off); + break; + case ALL: + Util.toast(context, R.string.download_repeat_all); + break; + case SINGLE: + Util.toast(context, R.string.download_repeat_single); + break; + default: + break; + } + updateRepeatButton(); + setControlsVisible(true); + } + }); + + toggleListButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + toggleFullscreenAlbumArt(); + setControlsVisible(true); + } + }); + + View overlay = rootView.findViewById(R.id.download_overlay_buttons); + final int overlayHeight = overlay != null ? overlay.getHeight() : -1; + albumArtImageView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + if (overlayHeight == -1 || lastY < (view.getBottom() - overlayHeight)) { + toggleFullscreenAlbumArt(); + setControlsVisible(true); + } + } + }); + + progressBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onStopTrackingTouch(final SeekBar seekBar) { + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + getDownloadService().seekTo(progressBar.getProgress()); + return null; + } + + @Override + protected void done(Void result) { + seekInProgress = false; + } + }.execute(); + } + + @Override + public void onStartTrackingTouch(final SeekBar seekBar) { + seekInProgress = true; + } + + @Override + public void onProgressChanged(final SeekBar seekBar, final int position, final boolean fromUser) { + if (fromUser) { + positionTextView.setText(Util.formatDuration(position / 1000)); + setControlsVisible(true); + } + } + }); + + return rootView; + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { + DownloadService downloadService = getDownloadService(); + if(Util.isOffline(context)) { + menuInflater.inflate(R.menu.nowplaying_offline, menu); + } else { + menuInflater.inflate(R.menu.nowplaying, menu); + } + if(downloadService != null && downloadService.isRemovePlayed()) { + menu.findItem(R.id.menu_remove_played).setChecked(true); + } + + if(downloadService != null) { + SharedPreferences prefs = Util.getPreferences(context); + boolean equalizerOn = prefs.getBoolean(Constants.PREFERENCES_EQUALIZER_ON, false); + if (equalizerOn && downloadService != null) { + if(downloadService.getEqualizerController() != null && downloadService.getEqualizerController().isEnabled()) { + menu.findItem(R.id.menu_equalizer).setChecked(true); + } + } + } else { + menu.removeItem(R.id.menu_equalizer); + } + + if(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_BATCH_MODE, false)) { + menu.findItem(R.id.menu_batch_mode).setChecked(true); + } + } + + @Override + public boolean onOptionsItemSelected(MenuItem menuItem) { + if(menuItemSelected(menuItem.getItemId(), null)) { + return true; + } + + return super.onOptionsItemSelected(menuItem); + } + + @Override + public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, DownloadFile downloadFile) { + if(Util.isOffline(context)) { + menuInflater.inflate(R.menu.nowplaying_context_offline, menu); + } else { + menuInflater.inflate(R.menu.nowplaying_context, menu); + } + + if (downloadFile.getSong().getParent() == null) { + menu.findItem(R.id.menu_show_album).setVisible(false); + menu.findItem(R.id.menu_show_artist).setVisible(false); + } + + MenuUtil.hideMenuItems(context, menu, updateView); + } + + @Override + public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, DownloadFile downloadFile) { + if(onContextItemSelected(menuItem, downloadFile.getSong())) { + return true; + } + + return menuItemSelected(menuItem.getItemId(), downloadFile); + } + + private boolean menuItemSelected(int menuItemId, final DownloadFile song) { + List songs; + switch (menuItemId) { + case R.id.menu_show_album: case R.id.menu_show_artist: + Entry entry = song.getSong(); + + Intent intent = new Intent(context, SubsonicFragmentActivity.class); + intent.putExtra(Constants.INTENT_EXTRA_VIEW_ALBUM, true); + String albumId; + String albumName; + if(menuItemId == R.id.menu_show_album) { + if(Util.isTagBrowsing(context)) { + albumId = entry.getAlbumId(); + } else { + albumId = entry.getParent(); + } + albumName = entry.getAlbum(); + } else { + if(Util.isTagBrowsing(context)) { + albumId = entry.getArtistId(); + } else { + albumId = entry.getGrandParent(); + if(albumId == null) { + intent.putExtra(Constants.INTENT_EXTRA_NAME_CHILD_ID, entry.getParent()); + } + } + albumName = entry.getArtist(); + intent.putExtra(Constants.INTENT_EXTRA_NAME_ARTIST, true); + } + intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, albumId); + intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, albumName); + intent.putExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE, "Artist"); + + if(Util.isOffline(context)) { + try { + // This should only be successful if this is a online song in offline mode + Integer.parseInt(entry.getParent()); + String root = FileUtil.getMusicDirectory(context).getPath(); + String id = root + "/" + entry.getPath(); + id = id.substring(0, id.lastIndexOf("/")); + if(menuItemId == R.id.menu_show_album) { + intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, id); + } + id = id.substring(0, id.lastIndexOf("/")); + if(menuItemId != R.id.menu_show_album) { + intent.putExtra(Constants.INTENT_EXTRA_NAME_ID, id); + intent.putExtra(Constants.INTENT_EXTRA_NAME_NAME, entry.getArtist()); + intent.removeExtra(Constants.INTENT_EXTRA_NAME_CHILD_ID); + } + } catch(Exception e) { + // Do nothing, entry.getParent() is fine + } + } + + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + Util.startActivityWithoutTransition(context, intent); + return true; + case R.id.menu_remove_all: + Util.confirmDialog(context, R.string.download_menu_remove_all, "", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + getDownloadService().setShufflePlayEnabled(false); + getDownloadService().clear(); + return null; + } + + @Override + protected void done(Void result) { + context.closeNowPlaying(); + } + }.execute(); + } + }); + return true; + case R.id.menu_remove_played: + if (getDownloadService().isRemovePlayed()) { + getDownloadService().setRemovePlayed(false); + } else { + getDownloadService().setRemovePlayed(true); + } + context.supportInvalidateOptionsMenu(); + return true; + case R.id.menu_shuffle: + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + getDownloadService().shuffle(); + return null; + } + + @Override + protected void done(Void result) { + Util.toast(context, R.string.download_menu_shuffle_notification); + } + }.execute(); + return true; + case R.id.menu_save_playlist: + List entries = new LinkedList(); + for (DownloadFile downloadFile : getDownloadService().getSongs()) { + entries.add(downloadFile.getSong()); + } + createNewPlaylist(entries, true); + return true; + case R.id.menu_info: + displaySongInfo(song.getSong()); + return true; + case R.id.menu_equalizer: { + DownloadService downloadService = getDownloadService(); + if (downloadService != null) { + EqualizerController controller = downloadService.getEqualizerController(); + if(controller != null) { + SubsonicFragment fragment = new EqualizerFragment(); + replaceFragment(fragment); + setControlsVisible(true); + + return true; + } + } + + // Any failed condition will get here + Util.toast(context, "Failed to start equalizer. Try restarting."); + return true; + }case R.id.menu_batch_mode: + if(Util.isBatchMode(context)) { + Util.setBatchMode(context, false); + songListAdapter.notifyDataSetChanged(); + } else { + Util.setBatchMode(context, true); + songListAdapter.notifyDataSetChanged(); + } + context.supportInvalidateOptionsMenu(); + + return true; + default: + return false; + } + } + + @Override + public void onResume() { + super.onResume(); + if(this.primaryFragment) { + onResumeHandlers(); + } else { + update(); + } + } + private void onResumeHandlers() { + executorService = Executors.newSingleThreadScheduledExecutor(); + setControlsVisible(true); + + final DownloadService downloadService = getDownloadService(); + if (downloadService == null || downloadService.getCurrentPlaying() == null || startFlipped) { + playlistFlipper.setDisplayedChild(1); + startFlipped = false; + } + + updateButtons(); + + if(currentPlaying == null && downloadService != null && currentPlaying == downloadService.getCurrentPlaying()) { + getImageLoader().loadImage(albumArtImageView, (Entry) null, true, false); + } + + context.runWhenServiceAvailable(new Runnable() { + @Override + public void run() { + if (primaryFragment) { + DownloadService downloadService = getDownloadService(); + downloadService.addOnSongChangedListener(NowPlayingFragment.this, true); + } + updateRepeatButton(); + updateTitle(); + } + }); + } + + @Override + public void onPause() { + super.onPause(); + onPauseHandlers(); + } + private void onPauseHandlers() { + if(executorService != null) { + DownloadService downloadService = getDownloadService(); + if (downloadService != null) { + downloadService.removeOnSongChangeListener(this); + } + playlistFlipper.setDisplayedChild(0); + } + } + + @Override + public void setPrimaryFragment(boolean primary) { + super.setPrimaryFragment(primary); + if(rootView != null) { + if(primary) { + onResumeHandlers(); + } else { + onPauseHandlers(); + } + } + } + + @Override + public void setTitle(int title) { + this.title = context.getResources().getString(title); + if(this.primaryFragment) { + context.setTitle(this.title); + } + } + @Override + public void setSubtitle(CharSequence title) { + this.subtitle = title; + if(this.primaryFragment) { + context.setSubtitle(title); + } + } + + @Override + public SectionAdapter getCurrentAdapter() { + return songListAdapter; + } + + private void scheduleHideControls() { + if (hideControlsFuture != null) { + hideControlsFuture.cancel(false); + } + + final Handler handler = new Handler(); + Runnable runnable = new Runnable() { + @Override + public void run() { + handler.post(new Runnable() { + @Override + public void run() { + setControlsVisible(false); + } + }); + } + }; + hideControlsFuture = executorService.schedule(runnable, 3000L, TimeUnit.MILLISECONDS); + } + + private void setControlsVisible(boolean visible) { + DownloadService downloadService = getDownloadService(); + try { + long duration = 1700L; + FadeOutAnimation.createAndStart(rootView.findViewById(R.id.download_overlay_buttons), !visible, duration); + + if (visible) { + scheduleHideControls(); + } + } catch(Exception e) { + + } + } + + private void updateButtons() { + if(context == null) { + return; + } + } + + // Scroll to current playing/downloading. + private void scrollToCurrent() { + if (getDownloadService() == null || songListAdapter == null) { + scrollWhenLoaded = true; + return; + } + + // Try to get position of current playing/downloading + int position = songListAdapter.getItemPosition(currentPlaying); + if(position == -1) { + DownloadFile currentDownloading = getDownloadService().getCurrentDownloading(); + position = songListAdapter.getItemPosition(currentDownloading); + } + + // If found, scroll to it + if(position != -1) { + // RecyclerView.scrollToPosition just puts it on the screen (ie: bottom if scrolled below it) + LinearLayoutManager layoutManager = (LinearLayoutManager) playlistView.getLayoutManager(); + layoutManager.scrollToPositionWithOffset(position, 0); + } + } + + private void update() { + if(startFlipped) { + startFlipped = false; + scrollToCurrent(); + } + } + + private int getMinutes(int progress) { + if(progress < 30) { + return progress + 1; + } else if(progress < 49) { + return (progress - 30) * 5 + getMinutes(29); + } else if(progress < 57) { + return (progress - 48) * 30 + getMinutes(48); + } else if(progress < 81) { + return (progress - 56) * 60 + getMinutes(56); + } else { + return (progress - 80) * 150 + getMinutes(80); + } + } + + private void toggleFullscreenAlbumArt() { + if (playlistFlipper.getDisplayedChild() == 1) { + playlistFlipper.setInAnimation(AnimationUtils.loadAnimation(context, R.anim.push_down_in)); + playlistFlipper.setOutAnimation(AnimationUtils.loadAnimation(context, R.anim.push_down_out)); + playlistFlipper.setDisplayedChild(0); + } else { + scrollToCurrent(); + playlistFlipper.setInAnimation(AnimationUtils.loadAnimation(context, R.anim.push_up_in)); + playlistFlipper.setOutAnimation(AnimationUtils.loadAnimation(context, R.anim.push_up_out)); + playlistFlipper.setDisplayedChild(1); + + UpdateView.triggerUpdate(); + } + } + + private void start() { + DownloadService service = getDownloadService(); + PlayerState state = service.getPlayerState(); + if (state == PAUSED || state == COMPLETED || state == STOPPED) { + service.start(); + } else if (state == STOPPED || state == IDLE) { + warnIfStorageUnavailable(); + int current = service.getCurrentPlayingIndex(); + // TODO: Use play() method. + if (current == -1) { + service.play(0); + } else { + service.play(current); + } + } + } + + private void changeProgress(final boolean rewind) { + final DownloadService downloadService = getDownloadService(); + if(downloadService == null) { + return; + } + + new SilentBackgroundTask(context) { + int seekTo; + + @Override + protected Void doInBackground() throws Throwable { + if(rewind) { + seekTo = downloadService.rewind(); + } else { + seekTo = downloadService.fastForward(); + } + return null; + } + + @Override + protected void done(Void result) { + progressBar.setProgress(seekTo); + } + }.execute(); + } + + @Override + public boolean onDown(MotionEvent me) { + setControlsVisible(true); + return false; + } + + @Override + public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { + final DownloadService downloadService = getDownloadService(); + if (downloadService == null || e1 == null || e2 == null) { + return false; + } + + // Right to Left swipe + int action = 0; + if (e1.getX() - e2.getX() > swipeDistance && Math.abs(velocityX) > swipeVelocity) { + action = ACTION_NEXT; + } + // Left to Right swipe + else if (e2.getX() - e1.getX() > swipeDistance && Math.abs(velocityX) > swipeVelocity) { + action = ACTION_PREVIOUS; + } + // Top to Bottom swipe + else if (e2.getY() - e1.getY() > swipeDistance && Math.abs(velocityY) > swipeVelocity) { + action = ACTION_FORWARD; + } + // Bottom to Top swipe + else if (e1.getY() - e2.getY() > swipeDistance && Math.abs(velocityY) > swipeVelocity) { + action = ACTION_REWIND; + } + + if(action > 0) { + final int performAction = action; + warnIfStorageUnavailable(); + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + switch(performAction) { + case ACTION_NEXT: + downloadService.next(); + break; + case ACTION_PREVIOUS: + downloadService.previous(); + break; + case ACTION_FORWARD: + downloadService.seekTo(downloadService.getPlayerPosition() + DownloadService.FAST_FORWARD); + break; + case ACTION_REWIND: + downloadService.seekTo(downloadService.getPlayerPosition() - DownloadService.REWIND); + break; + } + return null; + } + }.execute(); + + return true; + } else { + return false; + } + } + + @Override + public void onLongPress(MotionEvent e) { + } + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + return false; + } + + @Override + public void onShowPress(MotionEvent e) { + } + + @Override + public boolean onSingleTapUp(MotionEvent e) { + return false; + } + + @Override + public void onItemClicked(UpdateView updateView, final DownloadFile item) { + warnIfStorageUnavailable(); + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + getDownloadService().play(item); + return null; + } + }.execute(); + } + + @Override + public void onSongChanged(DownloadFile currentPlaying, int currentPlayingIndex) { + this.currentPlaying = currentPlaying; + setupSubtitle(currentPlayingIndex); if (currentPlaying != null && !currentPlaying.isSong()) { previousButton.setVisibility(View.GONE); @@ -918,189 +918,189 @@ public class NowPlayingFragment extends SubsonicFragment implements OnGestureLis rewindButton.setVisibility(View.GONE); fastforwardButton.setVisibility(View.GONE); - } - updateTitle(); - } + } + updateTitle(); + } - private void setupSubtitle(int currentPlayingIndex) { - if (currentPlaying != null) { - Entry song = currentPlaying.getSong(); - songTitleTextView.setText(song.getTitle()); - getImageLoader().loadImage(albumArtImageView, song, true, true); + private void setupSubtitle(int currentPlayingIndex) { + if (currentPlaying != null) { + Entry song = currentPlaying.getSong(); + songTitleTextView.setText(song.getTitle()); + getImageLoader().loadImage(albumArtImageView, song, true, true); - DownloadService downloadService = getDownloadService(); - if(downloadService.isShufflePlayEnabled()) { - setSubtitle(context.getResources().getString(R.string.download_playerstate_playing_shuffle)); - } else { - setSubtitle(context.getResources().getString(R.string.download_playing_out_of, currentPlayingIndex + 1, currentPlayingSize)); - } - } else { - songTitleTextView.setText(null); - getImageLoader().loadImage(albumArtImageView, (Entry) null, true, false); - setSubtitle(null); - } - } + DownloadService downloadService = getDownloadService(); + if(downloadService.isShufflePlayEnabled()) { + setSubtitle(context.getResources().getString(R.string.download_playerstate_playing_shuffle)); + } else { + setSubtitle(context.getResources().getString(R.string.download_playing_out_of, currentPlayingIndex + 1, currentPlayingSize)); + } + } else { + songTitleTextView.setText(null); + getImageLoader().loadImage(albumArtImageView, (Entry) null, true, false); + setSubtitle(null); + } + } - @Override - public void onSongsChanged(List songs, DownloadFile currentPlaying, int currentPlayingIndex) { - currentPlayingSize = songs.size(); + @Override + public void onSongsChanged(List songs, DownloadFile currentPlaying, int currentPlayingIndex) { + currentPlayingSize = songs.size(); - DownloadService downloadService = getDownloadService(); - if(downloadService.isShufflePlayEnabled()) { - emptyTextView.setText(R.string.download_shuffle_loading); - } - else { - emptyTextView.setText(R.string.download_empty); - } + DownloadService downloadService = getDownloadService(); + if(downloadService.isShufflePlayEnabled()) { + emptyTextView.setText(R.string.download_shuffle_loading); + } + else { + emptyTextView.setText(R.string.download_empty); + } - if(songListAdapter == null) { - songList = new ArrayList<>(); - songList.addAll(songs); - playlistView.setAdapter(songListAdapter = new DownloadFileAdapter(context, songList, NowPlayingFragment.this)); - } else { - songList.clear(); - songList.addAll(songs); - songListAdapter.notifyDataSetChanged(); - } + if(songListAdapter == null) { + songList = new ArrayList<>(); + songList.addAll(songs); + playlistView.setAdapter(songListAdapter = new DownloadFileAdapter(context, songList, NowPlayingFragment.this)); + } else { + songList.clear(); + songList.addAll(songs); + songListAdapter.notifyDataSetChanged(); + } - emptyTextView.setVisibility(songs.isEmpty() ? View.VISIBLE : View.GONE); + emptyTextView.setVisibility(songs.isEmpty() ? View.VISIBLE : View.GONE); - if(scrollWhenLoaded) { - scrollToCurrent(); - scrollWhenLoaded = false; - } + if(scrollWhenLoaded) { + scrollToCurrent(); + scrollWhenLoaded = false; + } - if(this.currentPlaying != currentPlaying) { - onSongChanged(currentPlaying, currentPlayingIndex); - onMetadataUpdate(currentPlaying != null ? currentPlaying.getSong() : null, DownloadService.METADATA_UPDATED_ALL); - } else { - setupSubtitle(currentPlayingIndex); - } + if(this.currentPlaying != currentPlaying) { + onSongChanged(currentPlaying, currentPlayingIndex); + onMetadataUpdate(currentPlaying != null ? currentPlaying.getSong() : null, DownloadService.METADATA_UPDATED_ALL); + } else { + setupSubtitle(currentPlayingIndex); + } toggleListButton.setVisibility(View.VISIBLE); repeatButton.setVisibility(View.VISIBLE); - } + } - @Override - public void onSongProgress(DownloadFile currentPlaying, int millisPlayed, Integer duration, boolean isSeekable) { - if (currentPlaying != null) { - int millisTotal = duration == null ? 0 : duration; + @Override + public void onSongProgress(DownloadFile currentPlaying, int millisPlayed, Integer duration, boolean isSeekable) { + if (currentPlaying != null) { + int millisTotal = duration == null ? 0 : duration; - positionTextView.setText(Util.formatDuration(millisPlayed / 1000)); - if(millisTotal > 0) { - durationTextView.setText(Util.formatDuration(millisTotal / 1000)); - } else { - durationTextView.setText("-:--"); - } - progressBar.setMax(millisTotal == 0 ? 100 : millisTotal); // Work-around for apparent bug. - if(!seekInProgress) { - progressBar.setProgress(millisPlayed); - } - progressBar.setEnabled(isSeekable); - } else { - positionTextView.setText("0:00"); - durationTextView.setText("-:--"); - progressBar.setProgress(0); - progressBar.setEnabled(false); - } - } + positionTextView.setText(Util.formatDuration(millisPlayed / 1000)); + if(millisTotal > 0) { + durationTextView.setText(Util.formatDuration(millisTotal / 1000)); + } else { + durationTextView.setText("-:--"); + } + progressBar.setMax(millisTotal == 0 ? 100 : millisTotal); // Work-around for apparent bug. + if(!seekInProgress) { + progressBar.setProgress(millisPlayed); + } + progressBar.setEnabled(isSeekable); + } else { + positionTextView.setText("0:00"); + durationTextView.setText("-:--"); + progressBar.setProgress(0); + progressBar.setEnabled(false); + } + } - @Override - public void onStateUpdate(DownloadFile downloadFile, PlayerState playerState) { - switch (playerState) { - case DOWNLOADING: - if(currentPlaying != null) { - if(Util.isWifiRequiredForDownload(context)) { - statusTextView.setText(context.getResources().getString(R.string.download_playerstate_mobile_disabled)); - } else { - long bytes = currentPlaying.getPartialFile().length(); - statusTextView.setText(context.getResources().getString(R.string.download_playerstate_downloading, Util.formatLocalizedBytes(bytes, context))); - } - } - break; - case PREPARING: - statusTextView.setText(R.string.download_playerstate_buffering); - break; - default: - if(currentPlaying != null) { - Entry entry = currentPlaying.getSong(); - if(entry.getAlbum() != null) { - String artist = ""; - if (entry.getArtist() != null) { - artist = currentPlaying.getSong().getArtist() + " - "; - } - statusTextView.setText(artist + entry.getAlbum()); - } else { - statusTextView.setText(null); - } - } else { - statusTextView.setText(null); - } - break; - } + @Override + public void onStateUpdate(DownloadFile downloadFile, PlayerState playerState) { + switch (playerState) { + case DOWNLOADING: + if(currentPlaying != null) { + if(Util.isWifiRequiredForDownload(context)) { + statusTextView.setText(context.getResources().getString(R.string.download_playerstate_mobile_disabled)); + } else { + long bytes = currentPlaying.getPartialFile().length(); + statusTextView.setText(context.getResources().getString(R.string.download_playerstate_downloading, Util.formatLocalizedBytes(bytes, context))); + } + } + break; + case PREPARING: + statusTextView.setText(R.string.download_playerstate_buffering); + break; + default: + if(currentPlaying != null) { + Entry entry = currentPlaying.getSong(); + if(entry.getAlbum() != null) { + String artist = ""; + if (entry.getArtist() != null) { + artist = currentPlaying.getSong().getArtist() + " - "; + } + statusTextView.setText(artist + entry.getAlbum()); + } else { + statusTextView.setText(null); + } + } else { + statusTextView.setText(null); + } + break; + } - switch (playerState) { - case STARTED: - pauseButton.setVisibility(View.VISIBLE); - stopButton.setVisibility(View.INVISIBLE); - startButton.setVisibility(View.INVISIBLE); - break; - case DOWNLOADING: - case PREPARING: - pauseButton.setVisibility(View.INVISIBLE); - stopButton.setVisibility(View.VISIBLE); - startButton.setVisibility(View.INVISIBLE); - break; - default: - pauseButton.setVisibility(View.INVISIBLE); - stopButton.setVisibility(View.INVISIBLE); - startButton.setVisibility(View.VISIBLE); - break; - } - } + switch (playerState) { + case STARTED: + pauseButton.setVisibility(View.VISIBLE); + stopButton.setVisibility(View.INVISIBLE); + startButton.setVisibility(View.INVISIBLE); + break; + case DOWNLOADING: + case PREPARING: + pauseButton.setVisibility(View.INVISIBLE); + stopButton.setVisibility(View.VISIBLE); + startButton.setVisibility(View.INVISIBLE); + break; + default: + pauseButton.setVisibility(View.INVISIBLE); + stopButton.setVisibility(View.INVISIBLE); + startButton.setVisibility(View.VISIBLE); + break; + } + } - @Override - public void onMetadataUpdate(Entry song, int fieldChange) { - if(song != null && albumArtImageView != null && fieldChange == DownloadService.METADATA_UPDATED_COVER_ART) { - getImageLoader().loadImage(albumArtImageView, song, true, true); - } - } + @Override + public void onMetadataUpdate(Entry song, int fieldChange) { + if(song != null && albumArtImageView != null && fieldChange == DownloadService.METADATA_UPDATED_COVER_ART) { + getImageLoader().loadImage(albumArtImageView, song, true, true); + } + } - public void updateRepeatButton() { - DownloadService downloadService = getDownloadService(); - switch (downloadService.getRepeatMode()) { - case OFF: - repeatButton.setImageResource(DrawableTint.getDrawableRes(context, R.attr.media_button_repeat_off)); - break; - case ALL: - repeatButton.setImageResource(DrawableTint.getDrawableRes(context, R.attr.media_button_repeat_all)); - break; - case SINGLE: - repeatButton.setImageResource(DrawableTint.getDrawableRes(context, R.attr.media_button_repeat_single)); - break; - default: - break; - } - } - private void updateTitle() { - DownloadService downloadService = getDownloadService(); + public void updateRepeatButton() { + DownloadService downloadService = getDownloadService(); + switch (downloadService.getRepeatMode()) { + case OFF: + repeatButton.setImageResource(DrawableTint.getDrawableRes(context, R.attr.media_button_repeat_off)); + break; + case ALL: + repeatButton.setImageResource(DrawableTint.getDrawableRes(context, R.attr.media_button_repeat_all)); + break; + case SINGLE: + repeatButton.setImageResource(DrawableTint.getDrawableRes(context, R.attr.media_button_repeat_single)); + break; + default: + break; + } + } + private void updateTitle() { + DownloadService downloadService = getDownloadService(); - String title = context.getResources().getString(R.string.button_bar_now_playing); + String title = context.getResources().getString(R.string.button_bar_now_playing); - setTitle(title); - } + setTitle(title); + } - @Override - protected List getSelectedEntries() { - List selected = getCurrentAdapter().getSelected(); - List entries = new ArrayList<>(); + @Override + protected List getSelectedEntries() { + List selected = getCurrentAdapter().getSelected(); + List entries = new ArrayList<>(); - for(DownloadFile downloadFile: selected) { - if(downloadFile.getSong() != null) { - entries.add(downloadFile.getSong()); - } - } + for(DownloadFile downloadFile: selected) { + if(downloadFile.getSong() != null) { + entries.add(downloadFile.getSong()); + } + } - return entries; - } + return entries; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/PreferenceCompatFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/PreferenceCompatFragment.java index cb79ae8..46ac06c 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/PreferenceCompatFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/PreferenceCompatFragment.java @@ -1,20 +1,20 @@ /* - This file is part of Subsonic. + This file is part of Subsonic. - Subsonic 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. + Subsonic 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. - Subsonic 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. + Subsonic 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 Subsonic. If not, see . + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.fragments; @@ -42,293 +42,293 @@ import net.nullsum.audinaut.R; import net.nullsum.audinaut.util.Constants; public abstract class PreferenceCompatFragment extends SubsonicFragment { - private static final String TAG = PreferenceCompatFragment.class.getSimpleName(); - private static final int FIRST_REQUEST_CODE = 100; - private static final int MSG_BIND_PREFERENCES = 1; - private static final String PREFERENCES_TAG = "android:preferences"; - private boolean mHavePrefs; - private boolean mInitDone; - private ListView mList; - private PreferenceManager mPreferenceManager; + private static final String TAG = PreferenceCompatFragment.class.getSimpleName(); + private static final int FIRST_REQUEST_CODE = 100; + private static final int MSG_BIND_PREFERENCES = 1; + private static final String PREFERENCES_TAG = "android:preferences"; + private boolean mHavePrefs; + private boolean mInitDone; + private ListView mList; + private PreferenceManager mPreferenceManager; - private Handler mHandler = new Handler() { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { + private Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { - case MSG_BIND_PREFERENCES: - bindPreferences(); - break; - } - } - }; + case MSG_BIND_PREFERENCES: + bindPreferences(); + break; + } + } + }; - final private Runnable mRequestFocus = new Runnable() { - public void run() { - mList.focusableViewAvailable(mList); - } - }; + final private Runnable mRequestFocus = new Runnable() { + public void run() { + mList.focusableViewAvailable(mList); + } + }; - private void bindPreferences() { - PreferenceScreen localPreferenceScreen = getPreferenceScreen(); - if (localPreferenceScreen != null) { - ListView localListView = getListView(); - localPreferenceScreen.bind(localListView); - } - } + private void bindPreferences() { + PreferenceScreen localPreferenceScreen = getPreferenceScreen(); + if (localPreferenceScreen != null) { + ListView localListView = getListView(); + localPreferenceScreen.bind(localListView); + } + } - private void ensureList() { - if (mList == null) { - View view = getView(); - if (view == null) { - throw new IllegalStateException("Content view not yet created"); - } + private void ensureList() { + if (mList == null) { + View view = getView(); + if (view == null) { + throw new IllegalStateException("Content view not yet created"); + } - View listView = view.findViewById(android.R.id.list); - if (!(listView instanceof ListView)) { - throw new RuntimeException("Content has view with id attribute 'android.R.id.list' that is not a ListView class"); - } + View listView = view.findViewById(android.R.id.list); + if (!(listView instanceof ListView)) { + throw new RuntimeException("Content has view with id attribute 'android.R.id.list' that is not a ListView class"); + } - mList = (ListView)listView; - if (mList == null) { - throw new RuntimeException("Your content must have a ListView whose id attribute is 'android.R.id.list'"); - } + mList = (ListView)listView; + if (mList == null) { + throw new RuntimeException("Your content must have a ListView whose id attribute is 'android.R.id.list'"); + } - mHandler.post(mRequestFocus); - } - } + mHandler.post(mRequestFocus); + } + } - private void postBindPreferences() { - if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) { - mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget(); - } - } + private void postBindPreferences() { + if (mHandler.hasMessages(MSG_BIND_PREFERENCES)) { + mHandler.obtainMessage(MSG_BIND_PREFERENCES).sendToTarget(); + } + } - private void requirePreferenceManager() { - if (this.mPreferenceManager == null) { - throw new RuntimeException("This should be called after super.onCreate."); - } - } + private void requirePreferenceManager() { + if (this.mPreferenceManager == null) { + throw new RuntimeException("This should be called after super.onCreate."); + } + } - public void addPreferencesFromIntent(Intent intent) { - requirePreferenceManager(); - PreferenceScreen screen = inflateFromIntent(intent, getPreferenceScreen()); - setPreferenceScreen(screen); - } + public void addPreferencesFromIntent(Intent intent) { + requirePreferenceManager(); + PreferenceScreen screen = inflateFromIntent(intent, getPreferenceScreen()); + setPreferenceScreen(screen); + } - public PreferenceScreen addPreferencesFromResource(int resId) { - requirePreferenceManager(); - PreferenceScreen screen = inflateFromResource(getActivity(), resId, getPreferenceScreen()); - setPreferenceScreen(screen); + public PreferenceScreen addPreferencesFromResource(int resId) { + requirePreferenceManager(); + PreferenceScreen screen = inflateFromResource(getActivity(), resId, getPreferenceScreen()); + setPreferenceScreen(screen); - for(int i = 0; i < screen.getPreferenceCount(); i++) { - Preference preference = screen.getPreference(i); - if(preference instanceof PreferenceScreen && preference.getKey() != null) { - preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - onStartNewFragment(preference.getKey()); - return false; - } - }); - } - } + for(int i = 0; i < screen.getPreferenceCount(); i++) { + Preference preference = screen.getPreference(i); + if(preference instanceof PreferenceScreen && preference.getKey() != null) { + preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + onStartNewFragment(preference.getKey()); + return false; + } + }); + } + } - return screen; - } + return screen; + } - public Preference findPreference(CharSequence key) { - if (mPreferenceManager == null) { - return null; - } - return mPreferenceManager.findPreference(key); - } + public Preference findPreference(CharSequence key) { + if (mPreferenceManager == null) { + return null; + } + return mPreferenceManager.findPreference(key); + } - public ListView getListView() { - ensureList(); - return mList; - } + public ListView getListView() { + ensureList(); + return mList; + } - public PreferenceManager getPreferenceManager() { - return mPreferenceManager; - } + public PreferenceManager getPreferenceManager() { + return mPreferenceManager; + } - @Override - public void onActivityCreated(Bundle savedInstanceState) { - super.onActivityCreated(savedInstanceState); - getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); - if (mHavePrefs) { - bindPreferences(); - } - mInitDone = true; - if (savedInstanceState != null) { - Bundle localBundle = savedInstanceState.getBundle(PREFERENCES_TAG); - if (localBundle != null) { - PreferenceScreen screen = getPreferenceScreen(); - if (screen != null) { - screen.restoreHierarchyState(localBundle); - } - } - } - } + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY); + if (mHavePrefs) { + bindPreferences(); + } + mInitDone = true; + if (savedInstanceState != null) { + Bundle localBundle = savedInstanceState.getBundle(PREFERENCES_TAG); + if (localBundle != null) { + PreferenceScreen screen = getPreferenceScreen(); + if (screen != null) { + screen.restoreHierarchyState(localBundle); + } + } + } + } - @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - dispatchActivityResult(requestCode, resultCode, data); - } + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + dispatchActivityResult(requestCode, resultCode, data); + } - @Override - public void onCreate(Bundle paramBundle) { - super.onCreate(paramBundle); - mPreferenceManager = createPreferenceManager(); + @Override + public void onCreate(Bundle paramBundle) { + super.onCreate(paramBundle); + mPreferenceManager = createPreferenceManager(); - int res = this.getArguments().getInt(Constants.INTENT_EXTRA_FRAGMENT_TYPE, 0); - if(res != 0) { - PreferenceScreen preferenceScreen = addPreferencesFromResource(res); - onInitPreferences(preferenceScreen); - } - } + int res = this.getArguments().getInt(Constants.INTENT_EXTRA_FRAGMENT_TYPE, 0); + if(res != 0) { + PreferenceScreen preferenceScreen = addPreferencesFromResource(res); + onInitPreferences(preferenceScreen); + } + } - @Override - public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup, Bundle paramBundle) { - return paramLayoutInflater.inflate(R.layout.preferences, paramViewGroup, false); - } + @Override + public View onCreateView(LayoutInflater paramLayoutInflater, ViewGroup paramViewGroup, Bundle paramBundle) { + return paramLayoutInflater.inflate(R.layout.preferences, paramViewGroup, false); + } - @Override - public void onDestroy() { - super.onDestroy(); - dispatchActivityDestroy(); - } + @Override + public void onDestroy() { + super.onDestroy(); + dispatchActivityDestroy(); + } - @Override - public void onDestroyView() { - mList = null; - mHandler.removeCallbacks(mRequestFocus); - mHandler.removeMessages(MSG_BIND_PREFERENCES); - super.onDestroyView(); - } + @Override + public void onDestroyView() { + mList = null; + mHandler.removeCallbacks(mRequestFocus); + mHandler.removeMessages(MSG_BIND_PREFERENCES); + super.onDestroyView(); + } - @Override - public void onSaveInstanceState(Bundle bundle) { - super.onSaveInstanceState(bundle); - PreferenceScreen screen = getPreferenceScreen(); - if (screen != null) { - Bundle localBundle = new Bundle(); - screen.saveHierarchyState(localBundle); - bundle.putBundle(PREFERENCES_TAG, localBundle); - } - } + @Override + public void onSaveInstanceState(Bundle bundle) { + super.onSaveInstanceState(bundle); + PreferenceScreen screen = getPreferenceScreen(); + if (screen != null) { + Bundle localBundle = new Bundle(); + screen.saveHierarchyState(localBundle); + bundle.putBundle(PREFERENCES_TAG, localBundle); + } + } - @Override - public void onStop() { - super.onStop(); - dispatchActivityStop(); - } + @Override + public void onStop() { + super.onStop(); + dispatchActivityStop(); + } - /** Access methods with visibility private **/ + /** Access methods with visibility private **/ - private PreferenceManager createPreferenceManager() { - try { - Constructor c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class); - c.setAccessible(true); - return c.newInstance(this.getActivity(), FIRST_REQUEST_CODE); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + private PreferenceManager createPreferenceManager() { + try { + Constructor c = PreferenceManager.class.getDeclaredConstructor(Activity.class, int.class); + c.setAccessible(true); + return c.newInstance(this.getActivity(), FIRST_REQUEST_CODE); + } catch (Exception e) { + throw new RuntimeException(e); + } + } - private PreferenceScreen getPreferenceScreen() { - try { - Method m = PreferenceManager.class.getDeclaredMethod("getPreferenceScreen"); - m.setAccessible(true); - return (PreferenceScreen) m.invoke(mPreferenceManager); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + private PreferenceScreen getPreferenceScreen() { + try { + Method m = PreferenceManager.class.getDeclaredMethod("getPreferenceScreen"); + m.setAccessible(true); + return (PreferenceScreen) m.invoke(mPreferenceManager); + } catch (Exception e) { + throw new RuntimeException(e); + } + } - protected void setPreferenceScreen(PreferenceScreen preferenceScreen) { - try { - Method m = PreferenceManager.class.getDeclaredMethod("setPreferences", PreferenceScreen.class); - m.setAccessible(true); - boolean result = (Boolean) m.invoke(mPreferenceManager, preferenceScreen); - if (result && preferenceScreen != null) { - mHavePrefs = true; - if (mInitDone) { - postBindPreferences(); - } - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } + protected void setPreferenceScreen(PreferenceScreen preferenceScreen) { + try { + Method m = PreferenceManager.class.getDeclaredMethod("setPreferences", PreferenceScreen.class); + m.setAccessible(true); + boolean result = (Boolean) m.invoke(mPreferenceManager, preferenceScreen); + if (result && preferenceScreen != null) { + mHavePrefs = true; + if (mInitDone) { + postBindPreferences(); + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } - private void dispatchActivityResult(int requestCode, int resultCode, Intent data) { - try { - Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityResult", int.class, int.class, Intent.class); - m.setAccessible(true); - m.invoke(mPreferenceManager, requestCode, resultCode, data); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + private void dispatchActivityResult(int requestCode, int resultCode, Intent data) { + try { + Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityResult", int.class, int.class, Intent.class); + m.setAccessible(true); + m.invoke(mPreferenceManager, requestCode, resultCode, data); + } catch (Exception e) { + throw new RuntimeException(e); + } + } - private void dispatchActivityDestroy() { - try { - Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityDestroy"); - m.setAccessible(true); - m.invoke(mPreferenceManager); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + private void dispatchActivityDestroy() { + try { + Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityDestroy"); + m.setAccessible(true); + m.invoke(mPreferenceManager); + } catch (Exception e) { + throw new RuntimeException(e); + } + } - private void dispatchActivityStop() { - try { - Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityStop"); - m.setAccessible(true); - m.invoke(mPreferenceManager); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + private void dispatchActivityStop() { + try { + Method m = PreferenceManager.class.getDeclaredMethod("dispatchActivityStop"); + m.setAccessible(true); + m.invoke(mPreferenceManager); + } catch (Exception e) { + throw new RuntimeException(e); + } + } - private void setFragment(PreferenceFragment preferenceFragment) { - try { - Method m = PreferenceManager.class.getDeclaredMethod("setFragment", PreferenceFragment.class); - m.setAccessible(true); - m.invoke(mPreferenceManager, preferenceFragment); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + private void setFragment(PreferenceFragment preferenceFragment) { + try { + Method m = PreferenceManager.class.getDeclaredMethod("setFragment", PreferenceFragment.class); + m.setAccessible(true); + m.invoke(mPreferenceManager, preferenceFragment); + } catch (Exception e) { + throw new RuntimeException(e); + } + } - public PreferenceScreen inflateFromResource(Context context, int resId, PreferenceScreen rootPreferences) { - PreferenceScreen preferenceScreen ; - try { - Method m = PreferenceManager.class.getDeclaredMethod("inflateFromResource", Context.class, int.class, PreferenceScreen.class); - m.setAccessible(true); - preferenceScreen = (PreferenceScreen) m.invoke(mPreferenceManager, context, resId, rootPreferences); - } catch (Exception e) { - throw new RuntimeException(e); - } - return preferenceScreen; - } + public PreferenceScreen inflateFromResource(Context context, int resId, PreferenceScreen rootPreferences) { + PreferenceScreen preferenceScreen ; + try { + Method m = PreferenceManager.class.getDeclaredMethod("inflateFromResource", Context.class, int.class, PreferenceScreen.class); + m.setAccessible(true); + preferenceScreen = (PreferenceScreen) m.invoke(mPreferenceManager, context, resId, rootPreferences); + } catch (Exception e) { + throw new RuntimeException(e); + } + return preferenceScreen; + } - public PreferenceScreen inflateFromIntent(Intent queryIntent, PreferenceScreen rootPreferences) { - PreferenceScreen preferenceScreen ; - try { - Method m = PreferenceManager.class.getDeclaredMethod("inflateFromIntent", Intent.class, PreferenceScreen.class); - m.setAccessible(true); - preferenceScreen = (PreferenceScreen) m.invoke(mPreferenceManager, queryIntent, rootPreferences); - } catch (Exception e) { - throw new RuntimeException(e); - } - return preferenceScreen; - } + public PreferenceScreen inflateFromIntent(Intent queryIntent, PreferenceScreen rootPreferences) { + PreferenceScreen preferenceScreen ; + try { + Method m = PreferenceManager.class.getDeclaredMethod("inflateFromIntent", Intent.class, PreferenceScreen.class); + m.setAccessible(true); + preferenceScreen = (PreferenceScreen) m.invoke(mPreferenceManager, queryIntent, rootPreferences); + } catch (Exception e) { + throw new RuntimeException(e); + } + return preferenceScreen; + } - protected abstract void onInitPreferences(PreferenceScreen preferenceScreen); - protected abstract void onStartNewFragment(String name); + protected abstract void onInitPreferences(PreferenceScreen preferenceScreen); + protected abstract void onStartNewFragment(String name); } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/SearchFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/SearchFragment.java index 40cbd6a..d950206 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/SearchFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/SearchFragment.java @@ -38,254 +38,254 @@ import net.nullsum.audinaut.util.Util; import net.nullsum.audinaut.view.UpdateView; public class SearchFragment extends SubsonicFragment implements SectionAdapter.OnItemClickedListener { - private static final String TAG = SearchFragment.class.getSimpleName(); + private static final String TAG = SearchFragment.class.getSimpleName(); - private static final int MAX_ARTISTS = 20; - private static final int MAX_ALBUMS = 20; - private static final int MAX_SONGS = 50; - private static final int MIN_CLOSENESS = 1; + private static final int MAX_ARTISTS = 20; + private static final int MAX_ALBUMS = 20; + private static final int MAX_SONGS = 50; + private static final int MIN_CLOSENESS = 1; - protected RecyclerView recyclerView; - protected SearchAdapter adapter; - protected boolean largeAlbums = false; + protected RecyclerView recyclerView; + protected SearchAdapter adapter; + protected boolean largeAlbums = false; - private SearchResult searchResult; - private boolean skipSearch = false; - private String currentQuery; + private SearchResult searchResult; + private boolean skipSearch = false; + private String currentQuery; - public SearchFragment() { - super(); - alwaysStartFullscreen = true; - } + public SearchFragment() { + super(); + alwaysStartFullscreen = true; + } - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); - if(savedInstanceState != null) { - searchResult = (SearchResult) savedInstanceState.getSerializable(Constants.FRAGMENT_LIST); - } - largeAlbums = Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_LARGE_ALBUM_ART, true); - } + if(savedInstanceState != null) { + searchResult = (SearchResult) savedInstanceState.getSerializable(Constants.FRAGMENT_LIST); + } + largeAlbums = Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_LARGE_ALBUM_ART, true); + } - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putSerializable(Constants.FRAGMENT_LIST, searchResult); - } + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putSerializable(Constants.FRAGMENT_LIST, searchResult); + } - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - rootView = inflater.inflate(R.layout.abstract_recycler_fragment, container, false); - setTitle(R.string.search_title); + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { + rootView = inflater.inflate(R.layout.abstract_recycler_fragment, container, false); + setTitle(R.string.search_title); - refreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout); - refreshLayout.setEnabled(false); + refreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout); + refreshLayout.setEnabled(false); - recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_recycler); - setupLayoutManager(recyclerView, largeAlbums); + recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_recycler); + setupLayoutManager(recyclerView, largeAlbums); - registerForContextMenu(recyclerView); - context.onNewIntent(context.getIntent()); + registerForContextMenu(recyclerView); + context.onNewIntent(context.getIntent()); - if(searchResult != null) { - skipSearch = true; - recyclerView.setAdapter(adapter = new SearchAdapter(context, searchResult, getImageLoader(), largeAlbums, this)); - } + if(searchResult != null) { + skipSearch = true; + recyclerView.setAdapter(adapter = new SearchAdapter(context, searchResult, getImageLoader(), largeAlbums, this)); + } - return rootView; - } + return rootView; + } - @Override - public void setIsOnlyVisible(boolean isOnlyVisible) { - boolean update = this.isOnlyVisible != isOnlyVisible; - super.setIsOnlyVisible(isOnlyVisible); - if(update && adapter != null) { - RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); - if(layoutManager instanceof GridLayoutManager) { - ((GridLayoutManager) layoutManager).setSpanCount(getRecyclerColumnCount()); - } - } - } + @Override + public void setIsOnlyVisible(boolean isOnlyVisible) { + boolean update = this.isOnlyVisible != isOnlyVisible; + super.setIsOnlyVisible(isOnlyVisible); + if(update && adapter != null) { + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + if(layoutManager instanceof GridLayoutManager) { + ((GridLayoutManager) layoutManager).setSpanCount(getRecyclerColumnCount()); + } + } + } - @Override - public GridLayoutManager.SpanSizeLookup getSpanSizeLookup(final GridLayoutManager gridLayoutManager) { - return new GridLayoutManager.SpanSizeLookup() { - @Override - public int getSpanSize(int position) { - int viewType = adapter.getItemViewType(position); - if(viewType == EntryGridAdapter.VIEW_TYPE_SONG || viewType == EntryGridAdapter.VIEW_TYPE_HEADER || viewType == ArtistAdapter.VIEW_TYPE_ARTIST) { - return gridLayoutManager.getSpanCount(); - } else { - return 1; - } - } - }; - } + @Override + public GridLayoutManager.SpanSizeLookup getSpanSizeLookup(final GridLayoutManager gridLayoutManager) { + return new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + int viewType = adapter.getItemViewType(position); + if(viewType == EntryGridAdapter.VIEW_TYPE_SONG || viewType == EntryGridAdapter.VIEW_TYPE_HEADER || viewType == ArtistAdapter.VIEW_TYPE_ARTIST) { + return gridLayoutManager.getSpanCount(); + } else { + return 1; + } + } + }; + } - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { - menuInflater.inflate(R.menu.search, menu); - onFinishSetupOptionsMenu(menu); - } + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { + menuInflater.inflate(R.menu.search, menu); + onFinishSetupOptionsMenu(menu); + } - @Override - public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Serializable item) { - onCreateContextMenuSupport(menu, menuInflater, updateView, item); - if(item instanceof MusicDirectory.Entry && !Util.isOffline(context)) { - menu.removeItem(R.id.song_menu_remove_playlist); - } - recreateContextMenu(menu); - } + @Override + public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Serializable item) { + onCreateContextMenuSupport(menu, menuInflater, updateView, item); + if(item instanceof MusicDirectory.Entry && !Util.isOffline(context)) { + menu.removeItem(R.id.song_menu_remove_playlist); + } + recreateContextMenu(menu); + } - @Override - public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Serializable item) { - return onContextItemSelected(menuItem, item); - } + @Override + public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Serializable item) { + return onContextItemSelected(menuItem, item); + } - @Override - public void refresh(boolean refresh) { - context.onNewIntent(context.getIntent()); - } + @Override + public void refresh(boolean refresh) { + context.onNewIntent(context.getIntent()); + } - @Override - public void onItemClicked(UpdateView updateView, Serializable item) { - if (item instanceof Artist) { - onArtistSelected((Artist) item, false); - } else if (item instanceof MusicDirectory.Entry) { - MusicDirectory.Entry entry = (MusicDirectory.Entry) item; - if (entry.isDirectory()) { - onAlbumSelected(entry, false); - } else { - onSongSelected(entry, false, true, true, false); - } - } - } + @Override + public void onItemClicked(UpdateView updateView, Serializable item) { + if (item instanceof Artist) { + onArtistSelected((Artist) item, false); + } else if (item instanceof MusicDirectory.Entry) { + MusicDirectory.Entry entry = (MusicDirectory.Entry) item; + if (entry.isDirectory()) { + onAlbumSelected(entry, false); + } else { + onSongSelected(entry, false, true, true, false); + } + } + } - @Override - protected List getSelectedEntries() { - List selected = adapter.getSelected(); - List selectedMedia = new ArrayList<>(); - for(Serializable ser: selected) { - if(ser instanceof MusicDirectory.Entry) { - selectedMedia.add((MusicDirectory.Entry) ser); - } - } + @Override + protected List getSelectedEntries() { + List selected = adapter.getSelected(); + List selectedMedia = new ArrayList<>(); + for(Serializable ser: selected) { + if(ser instanceof MusicDirectory.Entry) { + selectedMedia.add((MusicDirectory.Entry) ser); + } + } - return selectedMedia; - } + return selectedMedia; + } - @Override - protected boolean isShowArtistEnabled() { - return true; - } + @Override + protected boolean isShowArtistEnabled() { + return true; + } - public void search(final String query, final boolean autoplay) { - if(skipSearch) { - skipSearch = false; - return; - } - currentQuery = query; + public void search(final String query, final boolean autoplay) { + if(skipSearch) { + skipSearch = false; + return; + } + currentQuery = query; - BackgroundTask task = new TabBackgroundTask(this) { - @Override - protected SearchResult doInBackground() throws Throwable { - SearchCritera criteria = new SearchCritera(query, MAX_ARTISTS, MAX_ALBUMS, MAX_SONGS); - MusicService service = MusicServiceFactory.getMusicService(context); - return service.search(criteria, context, this); - } + BackgroundTask task = new TabBackgroundTask(this) { + @Override + protected SearchResult doInBackground() throws Throwable { + SearchCritera criteria = new SearchCritera(query, MAX_ARTISTS, MAX_ALBUMS, MAX_SONGS); + MusicService service = MusicServiceFactory.getMusicService(context); + return service.search(criteria, context, this); + } - @Override - protected void done(SearchResult result) { - searchResult = result; - recyclerView.setAdapter(adapter = new SearchAdapter(context, searchResult, getImageLoader(), largeAlbums, SearchFragment.this)); - if (autoplay) { - autoplay(query); - } + @Override + protected void done(SearchResult result) { + searchResult = result; + recyclerView.setAdapter(adapter = new SearchAdapter(context, searchResult, getImageLoader(), largeAlbums, SearchFragment.this)); + if (autoplay) { + autoplay(query); + } - } - }; - task.execute(); + } + }; + task.execute(); - if(searchItem != null) { - MenuItemCompat.collapseActionView(searchItem); - } - } + if(searchItem != null) { + MenuItemCompat.collapseActionView(searchItem); + } + } - protected String getCurrentQuery() { - return currentQuery; - } + protected String getCurrentQuery() { + return currentQuery; + } - private void onArtistSelected(Artist artist, boolean autoplay) { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_ID, artist.getId()); - args.putString(Constants.INTENT_EXTRA_NAME_NAME, artist.getName()); - if(autoplay) { - args.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true); - } - args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); - fragment.setArguments(args); + private void onArtistSelected(Artist artist, boolean autoplay) { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_ID, artist.getId()); + args.putString(Constants.INTENT_EXTRA_NAME_NAME, artist.getName()); + if(autoplay) { + args.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true); + } + args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); + fragment.setArguments(args); - replaceFragment(fragment); - } + replaceFragment(fragment); + } - private void onAlbumSelected(MusicDirectory.Entry album, boolean autoplay) { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_ID, album.getId()); - args.putString(Constants.INTENT_EXTRA_NAME_NAME, album.getTitle()); - if(autoplay) { - args.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true); - } - fragment.setArguments(args); + private void onAlbumSelected(MusicDirectory.Entry album, boolean autoplay) { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_ID, album.getId()); + args.putString(Constants.INTENT_EXTRA_NAME_NAME, album.getTitle()); + if(autoplay) { + args.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true); + } + fragment.setArguments(args); - replaceFragment(fragment); - } + replaceFragment(fragment); + } - private void onSongSelected(MusicDirectory.Entry song, boolean save, boolean append, boolean autoplay, boolean playNext) { - DownloadService downloadService = getDownloadService(); - if (downloadService != null) { - if (!append) { - downloadService.clear(); - } - downloadService.download(Arrays.asList(song), save, false, playNext, false); - if (autoplay) { - downloadService.play(downloadService.size() - 1); - } + private void onSongSelected(MusicDirectory.Entry song, boolean save, boolean append, boolean autoplay, boolean playNext) { + DownloadService downloadService = getDownloadService(); + if (downloadService != null) { + if (!append) { + downloadService.clear(); + } + downloadService.download(Arrays.asList(song), save, false, playNext, false); + if (autoplay) { + downloadService.play(downloadService.size() - 1); + } - Util.toast(context, getResources().getQuantityString(R.plurals.select_album_n_songs_added, 1, 1)); - } - } + Util.toast(context, getResources().getQuantityString(R.plurals.select_album_n_songs_added, 1, 1)); + } + } - private void autoplay(String query) { - query = query.toLowerCase(); + private void autoplay(String query) { + query = query.toLowerCase(); - Artist artist = null; - if(!searchResult.getArtists().isEmpty()) { - artist = searchResult.getArtists().get(0); - artist.setCloseness(Util.getStringDistance(artist.getName().toLowerCase(), query)); - } - MusicDirectory.Entry album = null; - if(!searchResult.getAlbums().isEmpty()) { - album = searchResult.getAlbums().get(0); - album.setCloseness(Util.getStringDistance(album.getTitle().toLowerCase(), query)); - } - MusicDirectory.Entry song = null; - if(!searchResult.getSongs().isEmpty()) { - song = searchResult.getSongs().get(0); - song.setCloseness(Util.getStringDistance(song.getTitle().toLowerCase(), query)); - } + Artist artist = null; + if(!searchResult.getArtists().isEmpty()) { + artist = searchResult.getArtists().get(0); + artist.setCloseness(Util.getStringDistance(artist.getName().toLowerCase(), query)); + } + MusicDirectory.Entry album = null; + if(!searchResult.getAlbums().isEmpty()) { + album = searchResult.getAlbums().get(0); + album.setCloseness(Util.getStringDistance(album.getTitle().toLowerCase(), query)); + } + MusicDirectory.Entry song = null; + if(!searchResult.getSongs().isEmpty()) { + song = searchResult.getSongs().get(0); + song.setCloseness(Util.getStringDistance(song.getTitle().toLowerCase(), query)); + } - if(artist != null && (artist.getCloseness() <= MIN_CLOSENESS || - (album == null || artist.getCloseness() <= album.getCloseness()) && - (song == null || artist.getCloseness() <= song.getCloseness()))) { - onArtistSelected(artist, true); - } else if(album != null && (album.getCloseness() <= MIN_CLOSENESS || - song == null || album.getCloseness() <= song.getCloseness())) { - onAlbumSelected(album, true); - } else if(song != null) { - onSongSelected(song, false, false, true, false); - } - } + if(artist != null && (artist.getCloseness() <= MIN_CLOSENESS || + (album == null || artist.getCloseness() <= album.getCloseness()) && + (song == null || artist.getCloseness() <= song.getCloseness()))) { + onArtistSelected(artist, true); + } else if(album != null && (album.getCloseness() <= MIN_CLOSENESS || + song == null || album.getCloseness() <= song.getCloseness())) { + onAlbumSelected(album, true); + } else if(song != null) { + onSongSelected(song, false, false, true, false); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/SelectArtistFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/SelectArtistFragment.java index 07b21c6..a397995 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/SelectArtistFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/SelectArtistFragment.java @@ -29,224 +29,224 @@ import java.util.ArrayList; import java.util.List; public class SelectArtistFragment extends SelectRecyclerFragment implements ArtistAdapter.OnMusicFolderChanged { - private static final String TAG = SelectArtistFragment.class.getSimpleName(); + private static final String TAG = SelectArtistFragment.class.getSimpleName(); - private List musicFolders = null; - private List entries; - private String groupId; - private String groupName; + private List musicFolders = null; + private List entries; + private String groupId; + private String groupName; - public SelectArtistFragment() { - super(); - } + public SelectArtistFragment() { + super(); + } - @Override - public void onCreate(Bundle bundle) { - super.onCreate(bundle); + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); - if(bundle != null) { - musicFolders = (List) bundle.getSerializable(Constants.FRAGMENT_LIST2); - } - artist = true; - } + if(bundle != null) { + musicFolders = (List) bundle.getSerializable(Constants.FRAGMENT_LIST2); + } + artist = true; + } - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putSerializable(Constants.FRAGMENT_LIST2, (Serializable) musicFolders); - } + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putSerializable(Constants.FRAGMENT_LIST2, (Serializable) musicFolders); + } - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - Bundle args = getArguments(); - if(args != null) { - if(args.getBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, false)) { - groupId = args.getString(Constants.INTENT_EXTRA_NAME_ID); - groupName = args.getString(Constants.INTENT_EXTRA_NAME_NAME); + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { + Bundle args = getArguments(); + if(args != null) { + if(args.getBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, false)) { + groupId = args.getString(Constants.INTENT_EXTRA_NAME_ID); + groupName = args.getString(Constants.INTENT_EXTRA_NAME_NAME); - if (groupName != null) { - setTitle(groupName); - context.invalidateOptionsMenu(); - } - } - } + if (groupName != null) { + setTitle(groupName); + context.invalidateOptionsMenu(); + } + } + } - super.onCreateView(inflater, container, bundle); + super.onCreateView(inflater, container, bundle); - return rootView; - } + return rootView; + } - @Override - public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Serializable item) { - onCreateContextMenuSupport(menu, menuInflater, updateView, item); - recreateContextMenu(menu); - } + @Override + public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Serializable item) { + onCreateContextMenuSupport(menu, menuInflater, updateView, item); + recreateContextMenu(menu); + } - @Override - public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Serializable item) { - return onContextItemSelected(menuItem, item); - } + @Override + public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Serializable item) { + return onContextItemSelected(menuItem, item); + } - @Override - public void onItemClicked(UpdateView updateView, Serializable item) { - SubsonicFragment fragment; - if(item instanceof Artist) { - Artist artist = (Artist) item; + @Override + public void onItemClicked(UpdateView updateView, Serializable item) { + SubsonicFragment fragment; + if(item instanceof Artist) { + Artist artist = (Artist) item; - if ((Util.isFirstLevelArtist(context) || Util.isOffline(context) || Util.isTagBrowsing(context)) || groupId != null) { - fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_ID, artist.getId()); - args.putString(Constants.INTENT_EXTRA_NAME_NAME, artist.getName()); + if ((Util.isFirstLevelArtist(context) || Util.isOffline(context) || Util.isTagBrowsing(context)) || groupId != null) { + fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_ID, artist.getId()); + args.putString(Constants.INTENT_EXTRA_NAME_NAME, artist.getName()); - if (!Util.isOffline(context)) { - args.putSerializable(Constants.INTENT_EXTRA_NAME_DIRECTORY, new Entry(artist)); - } - args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); + if (!Util.isOffline(context)) { + args.putSerializable(Constants.INTENT_EXTRA_NAME_DIRECTORY, new Entry(artist)); + } + args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); - fragment.setArguments(args); - } else { - fragment = new SelectArtistFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_ID, artist.getId()); - args.putString(Constants.INTENT_EXTRA_NAME_NAME, artist.getName()); - args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); - if (!Util.isOffline(context)) { - args.putSerializable(Constants.INTENT_EXTRA_NAME_DIRECTORY, new Entry(artist)); - } + fragment.setArguments(args); + } else { + fragment = new SelectArtistFragment(); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_ID, artist.getId()); + args.putString(Constants.INTENT_EXTRA_NAME_NAME, artist.getName()); + args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); + if (!Util.isOffline(context)) { + args.putSerializable(Constants.INTENT_EXTRA_NAME_DIRECTORY, new Entry(artist)); + } - fragment.setArguments(args); - } + fragment.setArguments(args); + } - replaceFragment(fragment); - } else { - Entry entry = (Entry) item; + replaceFragment(fragment); + } else { + Entry entry = (Entry) item; onSongPress(entries, entry); - } - } + } + } - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { - super.onCreateOptionsMenu(menu, menuInflater); + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { + super.onCreateOptionsMenu(menu, menuInflater); - if(Util.isOffline(context) || Util.isTagBrowsing(context) || groupId != null) { - menu.removeItem(R.id.menu_first_level_artist); - } else { - if (Util.isFirstLevelArtist(context)) { - menu.findItem(R.id.menu_first_level_artist).setChecked(true); - } - } - } + if(Util.isOffline(context) || Util.isTagBrowsing(context) || groupId != null) { + menu.removeItem(R.id.menu_first_level_artist); + } else { + if (Util.isFirstLevelArtist(context)) { + menu.findItem(R.id.menu_first_level_artist).setChecked(true); + } + } + } - @Override - public int getOptionsMenu() { - return R.menu.select_artist; - } + @Override + public int getOptionsMenu() { + return R.menu.select_artist; + } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - if(super.onOptionsItemSelected(item)) { - return true; - } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if(super.onOptionsItemSelected(item)) { + return true; + } - switch (item.getItemId()) { - case R.id.menu_first_level_artist: - toggleFirstLevelArtist(); - break; - } + switch (item.getItemId()) { + case R.id.menu_first_level_artist: + toggleFirstLevelArtist(); + break; + } - return false; - } + return false; + } - @Override - public SectionAdapter getAdapter(List objects) { - return new ArtistAdapter(context, objects, musicFolders, this, this); - } + @Override + public SectionAdapter getAdapter(List objects) { + return new ArtistAdapter(context, objects, musicFolders, this, this); + } - @Override - public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { - List items; - if(groupId == null) { - if (!Util.isOffline(context) && !Util.isTagBrowsing(context)) { - musicFolders = musicService.getMusicFolders(refresh, context, listener); + @Override + public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { + List items; + if(groupId == null) { + if (!Util.isOffline(context) && !Util.isTagBrowsing(context)) { + musicFolders = musicService.getMusicFolders(refresh, context, listener); - // Hide folders option if there is only one - if (musicFolders.size() == 1) { - musicFolders = null; - Util.setSelectedMusicFolderId(context, null); - } - } else { - musicFolders = null; - } - String musicFolderId = Util.getSelectedMusicFolderId(context); + // Hide folders option if there is only one + if (musicFolders.size() == 1) { + musicFolders = null; + Util.setSelectedMusicFolderId(context, null); + } + } else { + musicFolders = null; + } + String musicFolderId = Util.getSelectedMusicFolderId(context); - Indexes indexes = musicService.getIndexes(musicFolderId, refresh, context, listener); - indexes.sortChildren(context); - items = new ArrayList<>(indexes.getShortcuts().size() + indexes.getArtists().size()); - items.addAll(indexes.getShortcuts()); - items.addAll(indexes.getArtists()); - entries = indexes.getEntries(); - items.addAll(entries); - } else { - List artists = new ArrayList<>(); - items = new ArrayList<>(); - MusicDirectory dir = musicService.getMusicDirectory(groupId, groupName, refresh, context, listener); - for(Entry entry: dir.getChildren(true, false)) { - Artist artist = new Artist(); - artist.setId(entry.getId()); - artist.setName(entry.getTitle()); - artists.add(artist); - } + Indexes indexes = musicService.getIndexes(musicFolderId, refresh, context, listener); + indexes.sortChildren(context); + items = new ArrayList<>(indexes.getShortcuts().size() + indexes.getArtists().size()); + items.addAll(indexes.getShortcuts()); + items.addAll(indexes.getArtists()); + entries = indexes.getEntries(); + items.addAll(entries); + } else { + List artists = new ArrayList<>(); + items = new ArrayList<>(); + MusicDirectory dir = musicService.getMusicDirectory(groupId, groupName, refresh, context, listener); + for(Entry entry: dir.getChildren(true, false)) { + Artist artist = new Artist(); + artist.setId(entry.getId()); + artist.setName(entry.getTitle()); + artists.add(artist); + } - Indexes indexes = new Indexes(); - //indexes.setArtists = artists; - indexes.sortChildren(context); - items.addAll(indexes.getArtists()); + Indexes indexes = new Indexes(); + //indexes.setArtists = artists; + indexes.sortChildren(context); + items.addAll(indexes.getArtists()); - entries = dir.getChildren(false, true); - for(Entry entry: entries) { - items.add(entry); - } - } - - return items; - } + entries = dir.getChildren(false, true); + for(Entry entry: entries) { + items.add(entry); + } + } - @Override - public int getTitleResource() { - return groupId == null ? R.string.button_bar_browse : 0; - } + return items; + } - @Override - public void setEmpty(boolean empty) { - super.setEmpty(empty); + @Override + public int getTitleResource() { + return groupId == null ? R.string.button_bar_browse : 0; + } - if(empty && !Util.isOffline(context)) { - objects.clear(); - recyclerView.setAdapter(new ArtistAdapter(context, objects, musicFolders, this, this)); - recyclerView.setVisibility(View.VISIBLE); + @Override + public void setEmpty(boolean empty) { + super.setEmpty(empty); - View view = rootView.findViewById(R.id.tab_progress); - LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams(); - params.height = 0; - params.weight = 5; - view.setLayoutParams(params); - } - } + if(empty && !Util.isOffline(context)) { + objects.clear(); + recyclerView.setAdapter(new ArtistAdapter(context, objects, musicFolders, this, this)); + recyclerView.setVisibility(View.VISIBLE); - private void toggleFirstLevelArtist() { - Util.toggleFirstLevelArtist(context); - context.invalidateOptionsMenu(); - } + View view = rootView.findViewById(R.id.tab_progress); + LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) view.getLayoutParams(); + params.height = 0; + params.weight = 5; + view.setLayoutParams(params); + } + } - @Override - public void onMusicFolderChanged(MusicFolder selectedFolder) { - String startMusicFolderId = Util.getSelectedMusicFolderId(context); - String musicFolderId = selectedFolder == null ? null : selectedFolder.getId(); + private void toggleFirstLevelArtist() { + Util.toggleFirstLevelArtist(context); + context.invalidateOptionsMenu(); + } - if(!Util.equals(startMusicFolderId, musicFolderId)) { - Util.setSelectedMusicFolderId(context, musicFolderId); - context.invalidate(); - } - } + @Override + public void onMusicFolderChanged(MusicFolder selectedFolder) { + String startMusicFolderId = Util.getSelectedMusicFolderId(context); + String musicFolderId = selectedFolder == null ? null : selectedFolder.getId(); + + if(!Util.equals(startMusicFolderId, musicFolderId)) { + Util.setSelectedMusicFolderId(context, musicFolderId); + context.invalidate(); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/SelectDirectoryFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/SelectDirectoryFragment.java index 6d6e4cd..4f60608 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/SelectDirectoryFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/SelectDirectoryFragment.java @@ -67,145 +67,145 @@ import java.util.Set; import static net.nullsum.audinaut.domain.MusicDirectory.Entry; public class SelectDirectoryFragment extends SubsonicFragment implements SectionAdapter.OnItemClickedListener { - private static final String TAG = SelectDirectoryFragment.class.getSimpleName(); + private static final String TAG = SelectDirectoryFragment.class.getSimpleName(); - private RecyclerView recyclerView; - private FastScroller fastScroller; - private EntryGridAdapter entryGridAdapter; - private List albums; - private List entries; - private LoadTask currentTask; + private RecyclerView recyclerView; + private FastScroller fastScroller; + private EntryGridAdapter entryGridAdapter; + private List albums; + private List entries; + private LoadTask currentTask; - private SilentBackgroundTask updateCoverArtTask; - private ImageView coverArtView; - private Entry coverArtRep; - private String coverArtId; + private SilentBackgroundTask updateCoverArtTask; + private ImageView coverArtView; + private Entry coverArtRep; + private String coverArtId; - String id; - String name; - Entry directory; - String playlistId; - String playlistName; - boolean playlistOwner; - String albumListType; - String albumListExtra; - int albumListSize; - boolean refreshListing = false; - boolean restoredInstance = false; - boolean lookupParent = false; - boolean largeAlbums = false; - boolean topTracks = false; - String lookupEntry; + String id; + String name; + Entry directory; + String playlistId; + String playlistName; + boolean playlistOwner; + String albumListType; + String albumListExtra; + int albumListSize; + boolean refreshListing = false; + boolean restoredInstance = false; + boolean lookupParent = false; + boolean largeAlbums = false; + boolean topTracks = false; + String lookupEntry; - public SelectDirectoryFragment() { - super(); - } + public SelectDirectoryFragment() { + super(); + } - @Override - public void onCreate(Bundle bundle) { - super.onCreate(bundle); - if(bundle != null) { - entries = (List) bundle.getSerializable(Constants.FRAGMENT_LIST); - albums = (List) bundle.getSerializable(Constants.FRAGMENT_LIST2); - if(albums == null) { - albums = new ArrayList<>(); - } - restoredInstance = true; - } - } + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); + if(bundle != null) { + entries = (List) bundle.getSerializable(Constants.FRAGMENT_LIST); + albums = (List) bundle.getSerializable(Constants.FRAGMENT_LIST2); + if(albums == null) { + albums = new ArrayList<>(); + } + restoredInstance = true; + } + } - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putSerializable(Constants.FRAGMENT_LIST, (Serializable) entries); - outState.putSerializable(Constants.FRAGMENT_LIST2, (Serializable) albums); - } + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putSerializable(Constants.FRAGMENT_LIST, (Serializable) entries); + outState.putSerializable(Constants.FRAGMENT_LIST2, (Serializable) albums); + } - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - Bundle args = getArguments(); - if(args != null) { - id = args.getString(Constants.INTENT_EXTRA_NAME_ID); - name = args.getString(Constants.INTENT_EXTRA_NAME_NAME); - directory = (Entry) args.getSerializable(Constants.INTENT_EXTRA_NAME_DIRECTORY); - playlistId = args.getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID); - playlistName = args.getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME); - playlistOwner = args.getBoolean(Constants.INTENT_EXTRA_NAME_PLAYLIST_OWNER, false); - Object shareObj = args.getSerializable(Constants.INTENT_EXTRA_NAME_SHARE); - albumListType = args.getString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE); - albumListExtra = args.getString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA); - albumListSize = args.getInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0); - refreshListing = args.getBoolean(Constants.INTENT_EXTRA_REFRESH_LISTINGS); - artist = args.getBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, false); - lookupEntry = args.getString(Constants.INTENT_EXTRA_SEARCH_SONG); - topTracks = args.getBoolean(Constants.INTENT_EXTRA_TOP_TRACKS); + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { + Bundle args = getArguments(); + if(args != null) { + id = args.getString(Constants.INTENT_EXTRA_NAME_ID); + name = args.getString(Constants.INTENT_EXTRA_NAME_NAME); + directory = (Entry) args.getSerializable(Constants.INTENT_EXTRA_NAME_DIRECTORY); + playlistId = args.getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID); + playlistName = args.getString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME); + playlistOwner = args.getBoolean(Constants.INTENT_EXTRA_NAME_PLAYLIST_OWNER, false); + Object shareObj = args.getSerializable(Constants.INTENT_EXTRA_NAME_SHARE); + albumListType = args.getString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE); + albumListExtra = args.getString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA); + albumListSize = args.getInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 0); + refreshListing = args.getBoolean(Constants.INTENT_EXTRA_REFRESH_LISTINGS); + artist = args.getBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, false); + lookupEntry = args.getString(Constants.INTENT_EXTRA_SEARCH_SONG); + topTracks = args.getBoolean(Constants.INTENT_EXTRA_TOP_TRACKS); - String childId = args.getString(Constants.INTENT_EXTRA_NAME_CHILD_ID); - if(childId != null) { - id = childId; - lookupParent = true; - } - if(entries == null) { - entries = (List) args.getSerializable(Constants.FRAGMENT_LIST); - albums = (List) args.getSerializable(Constants.FRAGMENT_LIST2); + String childId = args.getString(Constants.INTENT_EXTRA_NAME_CHILD_ID); + if(childId != null) { + id = childId; + lookupParent = true; + } + if(entries == null) { + entries = (List) args.getSerializable(Constants.FRAGMENT_LIST); + albums = (List) args.getSerializable(Constants.FRAGMENT_LIST2); - if(albums == null) { - albums = new ArrayList(); - } - } - } + if(albums == null) { + albums = new ArrayList(); + } + } + } - rootView = inflater.inflate(R.layout.abstract_recycler_fragment, container, false); + rootView = inflater.inflate(R.layout.abstract_recycler_fragment, container, false); - refreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout); - refreshLayout.setOnRefreshListener(this); + refreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout); + refreshLayout.setOnRefreshListener(this); - if(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_LARGE_ALBUM_ART, true)) { - largeAlbums = true; - } + if(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_LARGE_ALBUM_ART, true)) { + largeAlbums = true; + } - recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_recycler); - recyclerView.setHasFixedSize(true); - fastScroller = (FastScroller) rootView.findViewById(R.id.fragment_fast_scroller); - setupScrollList(recyclerView); - setupLayoutManager(recyclerView, largeAlbums); + recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_recycler); + recyclerView.setHasFixedSize(true); + fastScroller = (FastScroller) rootView.findViewById(R.id.fragment_fast_scroller); + setupScrollList(recyclerView); + setupLayoutManager(recyclerView, largeAlbums); - if(entries == null) { - if(primaryFragment || secondaryFragment) { - load(false); - } else { - invalidated = true; - } - } else { + if(entries == null) { + if(primaryFragment || secondaryFragment) { + load(false); + } else { + invalidated = true; + } + } else { finishLoading(); - } + } - if(name != null) { - setTitle(name); - } + if(name != null) { + setTitle(name); + } - return rootView; - } + return rootView; + } - @Override - public void setIsOnlyVisible(boolean isOnlyVisible) { - boolean update = this.isOnlyVisible != isOnlyVisible; - super.setIsOnlyVisible(isOnlyVisible); - if(update && entryGridAdapter != null) { - RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); - if(layoutManager instanceof GridLayoutManager) { - ((GridLayoutManager) layoutManager).setSpanCount(getRecyclerColumnCount()); - } - } - } + @Override + public void setIsOnlyVisible(boolean isOnlyVisible) { + boolean update = this.isOnlyVisible != isOnlyVisible; + super.setIsOnlyVisible(isOnlyVisible); + if(update && entryGridAdapter != null) { + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + if(layoutManager instanceof GridLayoutManager) { + ((GridLayoutManager) layoutManager).setSpanCount(getRecyclerColumnCount()); + } + } + } - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { - if(albumListType != null) { - menuInflater.inflate(R.menu.select_album_list, menu); - } else if(artist) { - menuInflater.inflate(R.menu.select_album, menu); - } else { + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { + if(albumListType != null) { + menuInflater.inflate(R.menu.select_album_list, menu); + } else if(artist) { + menuInflater.inflate(R.menu.select_album, menu); + } else { if(Util.isOffline(context)) { menuInflater.inflate(R.menu.select_song_offline, menu); } @@ -216,611 +216,611 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Section menu.removeItem(R.id.menu_remove_playlist); } } - } - } + } + } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.menu_remove_playlist: - removeFromPlaylist(playlistId, playlistName, getSelectedIndexes()); - return true; - } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_remove_playlist: + removeFromPlaylist(playlistId, playlistName, getSelectedIndexes()); + return true; + } - return super.onOptionsItemSelected(item); + return super.onOptionsItemSelected(item); - } + } - @Override - public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Entry entry) { - onCreateContextMenuSupport(menu, menuInflater, updateView, entry); - if(!Util.isOffline(context) && (playlistId == null || !playlistOwner)) { - menu.removeItem(R.id.song_menu_remove_playlist); - } + @Override + public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Entry entry) { + onCreateContextMenuSupport(menu, menuInflater, updateView, entry); + if(!Util.isOffline(context) && (playlistId == null || !playlistOwner)) { + menu.removeItem(R.id.song_menu_remove_playlist); + } - recreateContextMenu(menu); - } - @Override - public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Entry entry) { - if(onContextItemSelected(menuItem, entry)) { - return true; - } + recreateContextMenu(menu); + } + @Override + public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Entry entry) { + if(onContextItemSelected(menuItem, entry)) { + return true; + } - switch (menuItem.getItemId()) { - case R.id.song_menu_remove_playlist: - removeFromPlaylist(playlistId, playlistName, Arrays.asList(entries.indexOf(entry))); - break; - } + switch (menuItem.getItemId()) { + case R.id.song_menu_remove_playlist: + removeFromPlaylist(playlistId, playlistName, Arrays.asList(entries.indexOf(entry))); + break; + } - return true; - } + return true; + } - @Override - public void onItemClicked(UpdateView updateView, Entry entry) { - if (entry.isDirectory()) { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getId()); - args.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getTitle()); - args.putSerializable(Constants.INTENT_EXTRA_NAME_DIRECTORY, entry); - if ("newest".equals(albumListType)) { - args.putBoolean(Constants.INTENT_EXTRA_REFRESH_LISTINGS, true); - } - if(!entry.isAlbum()) { - args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); - } - fragment.setArguments(args); + @Override + public void onItemClicked(UpdateView updateView, Entry entry) { + if (entry.isDirectory()) { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getId()); + args.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getTitle()); + args.putSerializable(Constants.INTENT_EXTRA_NAME_DIRECTORY, entry); + if ("newest".equals(albumListType)) { + args.putBoolean(Constants.INTENT_EXTRA_REFRESH_LISTINGS, true); + } + if(!entry.isAlbum()) { + args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); + } + fragment.setArguments(args); - replaceFragment(fragment, true); - } else { - onSongPress(entries, entry, albumListType == null); - } - } + replaceFragment(fragment, true); + } else { + onSongPress(entries, entry, albumListType == null); + } + } - @Override - protected void refresh(boolean refresh) { - load(refresh); - } + @Override + protected void refresh(boolean refresh) { + load(refresh); + } - @Override - protected boolean isShowArtistEnabled() { - return albumListType != null; - } + @Override + protected boolean isShowArtistEnabled() { + return albumListType != null; + } - private void load(boolean refresh) { - if(refreshListing) { - refresh = true; - } + private void load(boolean refresh) { + if(refreshListing) { + refresh = true; + } - if(currentTask != null) { - currentTask.cancel(); - } + if(currentTask != null) { + currentTask.cancel(); + } - recyclerView.setVisibility(View.INVISIBLE); - if (playlistId != null) { - getPlaylist(playlistId, playlistName, refresh); - } else if (albumListType != null) { - getAlbumList(albumListType, albumListSize, refresh); - } else { + recyclerView.setVisibility(View.INVISIBLE); + if (playlistId != null) { + getPlaylist(playlistId, playlistName, refresh); + } else if (albumListType != null) { + getAlbumList(albumListType, albumListSize, refresh); + } else { getMusicDirectory(id, name, refresh); - } - } + } + } - private void getMusicDirectory(final String id, final String name, final boolean refresh) { - setTitle(name); + private void getMusicDirectory(final String id, final String name, final boolean refresh) { + setTitle(name); - new LoadTask(refresh) { - @Override - protected MusicDirectory load(MusicService service) throws Exception { - MusicDirectory dir = getMusicDirectory(id, name, refresh, service, this); + new LoadTask(refresh) { + @Override + protected MusicDirectory load(MusicService service) throws Exception { + MusicDirectory dir = getMusicDirectory(id, name, refresh, service, this); - if(lookupParent && dir.getParent() != null) { - dir = getMusicDirectory(dir.getParent(), name, refresh, service, this); + if(lookupParent && dir.getParent() != null) { + dir = getMusicDirectory(dir.getParent(), name, refresh, service, this); - // Update the fragment pointers so other stuff works correctly - SelectDirectoryFragment.this.id = dir.getId(); - SelectDirectoryFragment.this.name = dir.getName(); - } else if(id != null && directory == null && dir.getParent() != null && !artist) { - MusicDirectory parentDir = getMusicDirectory(dir.getParent(), name, refresh, true, service, this); - for(Entry child: parentDir.getChildren()) { - if(id.equals(child.getId())) { - directory = child; - break; - } - } - } + // Update the fragment pointers so other stuff works correctly + SelectDirectoryFragment.this.id = dir.getId(); + SelectDirectoryFragment.this.name = dir.getName(); + } else if(id != null && directory == null && dir.getParent() != null && !artist) { + MusicDirectory parentDir = getMusicDirectory(dir.getParent(), name, refresh, true, service, this); + for(Entry child: parentDir.getChildren()) { + if(id.equals(child.getId())) { + directory = child; + break; + } + } + } - return dir; - } + return dir; + } - @Override - protected void done(Pair result) { - SelectDirectoryFragment.this.name = result.getFirst().getName(); - setTitle(SelectDirectoryFragment.this.name); - super.done(result); - } - }.execute(); - } + @Override + protected void done(Pair result) { + SelectDirectoryFragment.this.name = result.getFirst().getName(); + setTitle(SelectDirectoryFragment.this.name); + super.done(result); + } + }.execute(); + } - private void getRecursiveMusicDirectory(final String id, final String name, final boolean refresh) { - setTitle(name); + private void getRecursiveMusicDirectory(final String id, final String name, final boolean refresh) { + setTitle(name); - new LoadTask(refresh) { - @Override - protected MusicDirectory load(MusicService service) throws Exception { - MusicDirectory root = getMusicDirectory(id, name, refresh, service, this); - List songs = new ArrayList(); - getSongsRecursively(root, songs); - root.replaceChildren(songs); - return root; - } + new LoadTask(refresh) { + @Override + protected MusicDirectory load(MusicService service) throws Exception { + MusicDirectory root = getMusicDirectory(id, name, refresh, service, this); + List songs = new ArrayList(); + getSongsRecursively(root, songs); + root.replaceChildren(songs); + return root; + } - private void getSongsRecursively(MusicDirectory parent, List songs) throws Exception { - songs.addAll(parent.getChildren(false, true)); - for (Entry dir : parent.getChildren(true, false)) { - MusicService musicService = MusicServiceFactory.getMusicService(context); + private void getSongsRecursively(MusicDirectory parent, List songs) throws Exception { + songs.addAll(parent.getChildren(false, true)); + for (Entry dir : parent.getChildren(true, false)) { + MusicService musicService = MusicServiceFactory.getMusicService(context); - MusicDirectory musicDirectory; - if(Util.isTagBrowsing(context) && !Util.isOffline(context)) { - musicDirectory = musicService.getAlbum(dir.getId(), dir.getTitle(), false, context, this); - } else { - musicDirectory = musicService.getMusicDirectory(dir.getId(), dir.getTitle(), false, context, this); - } - getSongsRecursively(musicDirectory, songs); - } - } + MusicDirectory musicDirectory; + if(Util.isTagBrowsing(context) && !Util.isOffline(context)) { + musicDirectory = musicService.getAlbum(dir.getId(), dir.getTitle(), false, context, this); + } else { + musicDirectory = musicService.getMusicDirectory(dir.getId(), dir.getTitle(), false, context, this); + } + getSongsRecursively(musicDirectory, songs); + } + } - @Override - protected void done(Pair result) { - SelectDirectoryFragment.this.name = result.getFirst().getName(); - setTitle(SelectDirectoryFragment.this.name); - super.done(result); - } - }.execute(); - } + @Override + protected void done(Pair result) { + SelectDirectoryFragment.this.name = result.getFirst().getName(); + setTitle(SelectDirectoryFragment.this.name); + super.done(result); + } + }.execute(); + } - private void getPlaylist(final String playlistId, final String playlistName, final boolean refresh) { - setTitle(playlistName); + private void getPlaylist(final String playlistId, final String playlistName, final boolean refresh) { + setTitle(playlistName); - new LoadTask(refresh) { - @Override - protected MusicDirectory load(MusicService service) throws Exception { - return service.getPlaylist(refresh, playlistId, playlistName, context, this); - } - }.execute(); - } + new LoadTask(refresh) { + @Override + protected MusicDirectory load(MusicService service) throws Exception { + return service.getPlaylist(refresh, playlistId, playlistName, context, this); + } + }.execute(); + } - private void getAlbumList(final String albumListType, final int size, final boolean refresh) { - if ("random".equals(albumListType)) { - setTitle(R.string.main_albums_random); - } else if ("recent".equals(albumListType)) { - setTitle(R.string.main_albums_recent); - } else if ("frequent".equals(albumListType)) { - setTitle(R.string.main_albums_frequent); - } else if("genres".equals(albumListType) || "years".equals(albumListType)) { - setTitle(albumListExtra); - } else if("alphabeticalByName".equals(albumListType)) { - setTitle(R.string.main_albums_alphabetical); - } if (MainFragment.SONGS_NEWEST.equals(albumListType)) { - setTitle(R.string.main_songs_newest); - } else if (MainFragment.SONGS_TOP_PLAYED.equals(albumListType)) { - setTitle(R.string.main_songs_top_played); - } else if (MainFragment.SONGS_RECENT.equals(albumListType)) { - setTitle(R.string.main_songs_recent); - } else if (MainFragment.SONGS_FREQUENT.equals(albumListType)) { - setTitle(R.string.main_songs_frequent); - } + private void getAlbumList(final String albumListType, final int size, final boolean refresh) { + if ("random".equals(albumListType)) { + setTitle(R.string.main_albums_random); + } else if ("recent".equals(albumListType)) { + setTitle(R.string.main_albums_recent); + } else if ("frequent".equals(albumListType)) { + setTitle(R.string.main_albums_frequent); + } else if("genres".equals(albumListType) || "years".equals(albumListType)) { + setTitle(albumListExtra); + } else if("alphabeticalByName".equals(albumListType)) { + setTitle(R.string.main_albums_alphabetical); + } if (MainFragment.SONGS_NEWEST.equals(albumListType)) { + setTitle(R.string.main_songs_newest); + } else if (MainFragment.SONGS_TOP_PLAYED.equals(albumListType)) { + setTitle(R.string.main_songs_top_played); + } else if (MainFragment.SONGS_RECENT.equals(albumListType)) { + setTitle(R.string.main_songs_recent); + } else if (MainFragment.SONGS_FREQUENT.equals(albumListType)) { + setTitle(R.string.main_songs_frequent); + } - new LoadTask(true) { - @Override - protected MusicDirectory load(MusicService service) throws Exception { - MusicDirectory result; - if("genres".equals(albumListType) || "years".equals(albumListType)) { - result = service.getAlbumList(albumListType, albumListExtra, size, 0, refresh, context, this); - if(result.getChildrenSize() == 0 && "genres".equals(albumListType)) { - SelectDirectoryFragment.this.albumListType = "genres-songs"; - result = service.getSongsByGenre(albumListExtra, size, 0, context, this); - } - } else if("genres".equals(albumListType) || "genres-songs".equals(albumListType)) { - result = service.getSongsByGenre(albumListExtra, size, 0, context, this); - } else if(albumListType.indexOf(MainFragment.SONGS_LIST_PREFIX) != -1) { - result = service.getSongList(albumListType, size, 0, context, this); - } else { - result = service.getAlbumList(albumListType, size, 0, refresh, context, this); - } - return result; - } - }.execute(); - } + new LoadTask(true) { + @Override + protected MusicDirectory load(MusicService service) throws Exception { + MusicDirectory result; + if("genres".equals(albumListType) || "years".equals(albumListType)) { + result = service.getAlbumList(albumListType, albumListExtra, size, 0, refresh, context, this); + if(result.getChildrenSize() == 0 && "genres".equals(albumListType)) { + SelectDirectoryFragment.this.albumListType = "genres-songs"; + result = service.getSongsByGenre(albumListExtra, size, 0, context, this); + } + } else if("genres".equals(albumListType) || "genres-songs".equals(albumListType)) { + result = service.getSongsByGenre(albumListExtra, size, 0, context, this); + } else if(albumListType.indexOf(MainFragment.SONGS_LIST_PREFIX) != -1) { + result = service.getSongList(albumListType, size, 0, context, this); + } else { + result = service.getAlbumList(albumListType, size, 0, refresh, context, this); + } + return result; + } + }.execute(); + } - private abstract class LoadTask extends TabBackgroundTask> { - private boolean refresh; + private abstract class LoadTask extends TabBackgroundTask> { + private boolean refresh; - public LoadTask(boolean refresh) { - super(SelectDirectoryFragment.this); - this.refresh = refresh; + public LoadTask(boolean refresh) { + super(SelectDirectoryFragment.this); + this.refresh = refresh; - currentTask = this; - } + currentTask = this; + } - protected abstract MusicDirectory load(MusicService service) throws Exception; + protected abstract MusicDirectory load(MusicService service) throws Exception; - @Override - protected Pair doInBackground() throws Throwable { - MusicService musicService = MusicServiceFactory.getMusicService(context); - MusicDirectory dir = load(musicService); + @Override + protected Pair doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + MusicDirectory dir = load(musicService); - albums = dir.getChildren(true, false); - entries = dir.getChildren(); + albums = dir.getChildren(true, false); + entries = dir.getChildren(); - // This isn't really an artist if no albums on it! - if(albums.size() == 0) { - artist = false; - } + // This isn't really an artist if no albums on it! + if(albums.size() == 0) { + artist = false; + } - return new Pair<>(dir, true); - } + return new Pair<>(dir, true); + } - @Override - protected void done(Pair result) { - finishLoading(); - currentTask = null; - } + @Override + protected void done(Pair result) { + finishLoading(); + currentTask = null; + } - @Override - public void updateCache(int changeCode) { - if(entryGridAdapter != null && changeCode == CachedMusicService.CACHE_UPDATE_LIST) { - entryGridAdapter.notifyDataSetChanged(); - } else if(changeCode == CachedMusicService.CACHE_UPDATE_METADATA) { - if(coverArtView != null && coverArtRep != null && !Util.equals(coverArtRep.getCoverArt(), coverArtId)) { - synchronized (coverArtRep) { - if (updateCoverArtTask != null && updateCoverArtTask.isRunning()) { - updateCoverArtTask.cancel(); - } - updateCoverArtTask = getImageLoader().loadImage(coverArtView, coverArtRep, false, true); - coverArtId = coverArtRep.getCoverArt(); - } - } - } - } - } + @Override + public void updateCache(int changeCode) { + if(entryGridAdapter != null && changeCode == CachedMusicService.CACHE_UPDATE_LIST) { + entryGridAdapter.notifyDataSetChanged(); + } else if(changeCode == CachedMusicService.CACHE_UPDATE_METADATA) { + if(coverArtView != null && coverArtRep != null && !Util.equals(coverArtRep.getCoverArt(), coverArtId)) { + synchronized (coverArtRep) { + if (updateCoverArtTask != null && updateCoverArtTask.isRunning()) { + updateCoverArtTask.cancel(); + } + updateCoverArtTask = getImageLoader().loadImage(coverArtView, coverArtRep, false, true); + coverArtId = coverArtRep.getCoverArt(); + } + } + } + } + } - @Override - public SectionAdapter getCurrentAdapter() { - return entryGridAdapter; - } + @Override + public SectionAdapter getCurrentAdapter() { + return entryGridAdapter; + } - @Override - public GridLayoutManager.SpanSizeLookup getSpanSizeLookup(final GridLayoutManager gridLayoutManager) { - return new GridLayoutManager.SpanSizeLookup() { - @Override - public int getSpanSize(int position) { - int viewType = entryGridAdapter.getItemViewType(position); - if(viewType == EntryGridAdapter.VIEW_TYPE_SONG || viewType == EntryGridAdapter.VIEW_TYPE_HEADER || viewType == EntryInfiniteGridAdapter.VIEW_TYPE_LOADING) { - return gridLayoutManager.getSpanCount(); - } else { - return 1; - } - } - }; - } + @Override + public GridLayoutManager.SpanSizeLookup getSpanSizeLookup(final GridLayoutManager gridLayoutManager) { + return new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + int viewType = entryGridAdapter.getItemViewType(position); + if(viewType == EntryGridAdapter.VIEW_TYPE_SONG || viewType == EntryGridAdapter.VIEW_TYPE_HEADER || viewType == EntryInfiniteGridAdapter.VIEW_TYPE_LOADING) { + return gridLayoutManager.getSpanCount(); + } else { + return 1; + } + } + }; + } private void finishLoading() { - boolean validData = !entries.isEmpty() || !albums.isEmpty(); - if(!validData) { - setEmpty(true); - } + boolean validData = !entries.isEmpty() || !albums.isEmpty(); + if(!validData) { + setEmpty(true); + } - if(validData) { - recyclerView.setVisibility(View.VISIBLE); - } + if(validData) { + recyclerView.setVisibility(View.VISIBLE); + } - if(albumListType == null) { - entryGridAdapter = new EntryGridAdapter(context, entries, getImageLoader(), largeAlbums); - entryGridAdapter.setRemoveFromPlaylist(playlistId != null); - } else { - if("alphabeticalByName".equals(albumListType)) { - entryGridAdapter = new AlphabeticalAlbumAdapter(context, entries, getImageLoader(), largeAlbums); - } else { - entryGridAdapter = new EntryInfiniteGridAdapter(context, entries, getImageLoader(), largeAlbums); - } + if(albumListType == null) { + entryGridAdapter = new EntryGridAdapter(context, entries, getImageLoader(), largeAlbums); + entryGridAdapter.setRemoveFromPlaylist(playlistId != null); + } else { + if("alphabeticalByName".equals(albumListType)) { + entryGridAdapter = new AlphabeticalAlbumAdapter(context, entries, getImageLoader(), largeAlbums); + } else { + entryGridAdapter = new EntryInfiniteGridAdapter(context, entries, getImageLoader(), largeAlbums); + } - // Setup infinite loading based on scrolling - final EntryInfiniteGridAdapter infiniteGridAdapter = (EntryInfiniteGridAdapter) entryGridAdapter; - infiniteGridAdapter.setData(albumListType, albumListExtra, albumListSize); + // Setup infinite loading based on scrolling + final EntryInfiniteGridAdapter infiniteGridAdapter = (EntryInfiniteGridAdapter) entryGridAdapter; + infiniteGridAdapter.setData(albumListType, albumListExtra, albumListSize); - recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - super.onScrollStateChanged(recyclerView, newState); - } + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + } - @Override - public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - super.onScrolled(recyclerView, dx, dy); + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + super.onScrolled(recyclerView, dx, dy); - RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); - int totalItemCount = layoutManager.getItemCount(); - int lastVisibleItem; - if(layoutManager instanceof GridLayoutManager) { - lastVisibleItem = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition(); - } else if(layoutManager instanceof LinearLayoutManager) { - lastVisibleItem = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition(); - } else { - return; - } + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + int totalItemCount = layoutManager.getItemCount(); + int lastVisibleItem; + if(layoutManager instanceof GridLayoutManager) { + lastVisibleItem = ((GridLayoutManager) layoutManager).findLastVisibleItemPosition(); + } else if(layoutManager instanceof LinearLayoutManager) { + lastVisibleItem = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition(); + } else { + return; + } - if(totalItemCount > 0 && lastVisibleItem >= totalItemCount - 2) { - infiniteGridAdapter.loadMore(); - } - } - }); - } - entryGridAdapter.setOnItemClickedListener(this); - // Always show artist if this is not a artist we are viewing - if(!artist) { - entryGridAdapter.setShowArtist(true); - } - if(topTracks) { - entryGridAdapter.setShowAlbum(true); - } + if(totalItemCount > 0 && lastVisibleItem >= totalItemCount - 2) { + infiniteGridAdapter.loadMore(); + } + } + }); + } + entryGridAdapter.setOnItemClickedListener(this); + // Always show artist if this is not a artist we are viewing + if(!artist) { + entryGridAdapter.setShowArtist(true); + } + if(topTracks) { + entryGridAdapter.setShowAlbum(true); + } - int scrollToPosition = -1; - if(lookupEntry != null) { - for(int i = 0; i < entries.size(); i++) { - if(lookupEntry.equals(entries.get(i).getTitle())) { - scrollToPosition = i; - entryGridAdapter.addSelected(entries.get(i)); - lookupEntry = null; - break; - } - } - } + int scrollToPosition = -1; + if(lookupEntry != null) { + for(int i = 0; i < entries.size(); i++) { + if(lookupEntry.equals(entries.get(i).getTitle())) { + scrollToPosition = i; + entryGridAdapter.addSelected(entries.get(i)); + lookupEntry = null; + break; + } + } + } - recyclerView.setAdapter(entryGridAdapter); - fastScroller.attachRecyclerView(recyclerView); - context.supportInvalidateOptionsMenu(); + recyclerView.setAdapter(entryGridAdapter); + fastScroller.attachRecyclerView(recyclerView); + context.supportInvalidateOptionsMenu(); - if(scrollToPosition != -1) { - recyclerView.scrollToPosition(scrollToPosition); - } + if(scrollToPosition != -1) { + recyclerView.scrollToPosition(scrollToPosition); + } - Bundle args = getArguments(); - boolean playAll = args.getBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false); - if (playAll && !restoredInstance) { - playAll(args.getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, false), false, false); - } - } + Bundle args = getArguments(); + boolean playAll = args.getBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false); + if (playAll && !restoredInstance) { + playAll(args.getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, false), false, false); + } + } - @Override - protected void playNow(final boolean shuffle, final boolean append, final boolean playNext) { - List songs = getSelectedEntries(); - if(!songs.isEmpty()) { - download(songs, append, false, !append, playNext, shuffle); - entryGridAdapter.clearSelected(); - } else { - playAll(shuffle, append, playNext); - } - } - private void playAll(final boolean shuffle, final boolean append, final boolean playNext) { - boolean hasSubFolders = albums != null && !albums.isEmpty(); + @Override + protected void playNow(final boolean shuffle, final boolean append, final boolean playNext) { + List songs = getSelectedEntries(); + if(!songs.isEmpty()) { + download(songs, append, false, !append, playNext, shuffle); + entryGridAdapter.clearSelected(); + } else { + playAll(shuffle, append, playNext); + } + } + private void playAll(final boolean shuffle, final boolean append, final boolean playNext) { + boolean hasSubFolders = albums != null && !albums.isEmpty(); - if (hasSubFolders && id != null) { - downloadRecursively(id, false, append, !append, shuffle, false, playNext); - } else if(hasSubFolders && albumListType != null) { - downloadRecursively(albums, shuffle, append, playNext); - } else { - download(entries, append, false, !append, playNext, shuffle); - } - } + if (hasSubFolders && id != null) { + downloadRecursively(id, false, append, !append, shuffle, false, playNext); + } else if(hasSubFolders && albumListType != null) { + downloadRecursively(albums, shuffle, append, playNext); + } else { + download(entries, append, false, !append, playNext, shuffle); + } + } - private List getSelectedIndexes() { - List selected = entryGridAdapter.getSelected(); - List indexes = new ArrayList(); + private List getSelectedIndexes() { + List selected = entryGridAdapter.getSelected(); + List indexes = new ArrayList(); - for(Entry entry: selected) { - indexes.add(entries.indexOf(entry)); - } + for(Entry entry: selected) { + indexes.add(entries.indexOf(entry)); + } - return indexes; - } + return indexes; + } - @Override - protected void downloadBackground(final boolean save) { - List songs = getSelectedEntries(); - if(playlistId != null) { - songs = entries; - } + @Override + protected void downloadBackground(final boolean save) { + List songs = getSelectedEntries(); + if(playlistId != null) { + songs = entries; + } - if(songs.isEmpty()) { - // Get both songs and albums - downloadRecursively(id, save, false, false, false, true); - } else { - downloadBackground(save, songs); - } - } - @Override - protected void downloadBackground(final boolean save, final List entries) { - if (getDownloadService() == null) { - return; - } + if(songs.isEmpty()) { + // Get both songs and albums + downloadRecursively(id, save, false, false, false, true); + } else { + downloadBackground(save, songs); + } + } + @Override + protected void downloadBackground(final boolean save, final List entries) { + if (getDownloadService() == null) { + return; + } - warnIfStorageUnavailable(); - RecursiveLoader onValid = new RecursiveLoader(context) { - @Override - protected Boolean doInBackground() throws Throwable { - getSongsRecursively(entries, true); - getDownloadService().downloadBackground(songs, save); - return null; - } + warnIfStorageUnavailable(); + RecursiveLoader onValid = new RecursiveLoader(context) { + @Override + protected Boolean doInBackground() throws Throwable { + getSongsRecursively(entries, true); + getDownloadService().downloadBackground(songs, save); + return null; + } - @Override - protected void done(Boolean result) { - Util.toast(context, context.getResources().getQuantityString(R.plurals.select_album_n_songs_downloading, songs.size(), songs.size())); - } - }; - } + @Override + protected void done(Boolean result) { + Util.toast(context, context.getResources().getQuantityString(R.plurals.select_album_n_songs_downloading, songs.size(), songs.size())); + } + }; + } - @Override - protected void download(List entries, boolean append, boolean save, boolean autoplay, boolean playNext, boolean shuffle) { - download(entries, append, save, autoplay, playNext, shuffle, playlistName, playlistId); - } + @Override + protected void download(List entries, boolean append, boolean save, boolean autoplay, boolean playNext, boolean shuffle) { + download(entries, append, save, autoplay, playNext, shuffle, playlistName, playlistId); + } - @Override - protected void delete() { - List songs = getSelectedEntries(); - if(songs.isEmpty()) { - for(Entry entry: entries) { - if(entry.isDirectory()) { - deleteRecursively(entry); - } else { - songs.add(entry); - } - } - } - if (getDownloadService() != null) { - getDownloadService().delete(songs); - } - } + @Override + protected void delete() { + List songs = getSelectedEntries(); + if(songs.isEmpty()) { + for(Entry entry: entries) { + if(entry.isDirectory()) { + deleteRecursively(entry); + } else { + songs.add(entry); + } + } + } + if (getDownloadService() != null) { + getDownloadService().delete(songs); + } + } - public void removeFromPlaylist(final String id, final String name, final List indexes) { - new LoadingTask(context, true) { - @Override - protected Void doInBackground() throws Throwable { - MusicService musicService = MusicServiceFactory.getMusicService(context); - musicService.removeFromPlaylist(id, indexes, context, null); - return null; - } + public void removeFromPlaylist(final String id, final String name, final List indexes) { + new LoadingTask(context, true) { + @Override + protected Void doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + musicService.removeFromPlaylist(id, indexes, context, null); + return null; + } - @Override - protected void done(Void result) { - for(Integer index: indexes) { - entryGridAdapter.removeAt(index); - } - Util.toast(context, context.getResources().getString(R.string.removed_playlist, indexes.size(), name)); - } + @Override + protected void done(Void result) { + for(Integer index: indexes) { + entryGridAdapter.removeAt(index); + } + Util.toast(context, context.getResources().getString(R.string.removed_playlist, indexes.size(), name)); + } - @Override - protected void error(Throwable error) { - String msg; - if (error instanceof OfflineException) { - msg = getErrorMessage(error); - } else { - msg = context.getResources().getString(R.string.updated_playlist_error, name) + " " + getErrorMessage(error); - } + @Override + protected void error(Throwable error) { + String msg; + if (error instanceof OfflineException) { + msg = getErrorMessage(error); + } else { + msg = context.getResources().getString(R.string.updated_playlist_error, name) + " " + getErrorMessage(error); + } - Util.toast(context, msg, false); - } - }.execute(); - } - - private void showTopTracks() { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(getArguments()); - args.putBoolean(Constants.INTENT_EXTRA_TOP_TRACKS, true); - fragment.setArguments(args); + Util.toast(context, msg, false); + } + }.execute(); + } - replaceFragment(fragment, true); - } + private void showTopTracks() { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(getArguments()); + args.putBoolean(Constants.INTENT_EXTRA_TOP_TRACKS, true); + fragment.setArguments(args); - private View createHeader() { - View header = LayoutInflater.from(context).inflate(R.layout.select_album_header, null, false); + replaceFragment(fragment, true); + } - setupCoverArt(header); - setupTextDisplay(header); + private View createHeader() { + View header = LayoutInflater.from(context).inflate(R.layout.select_album_header, null, false); - return header; - } + setupCoverArt(header); + setupTextDisplay(header); - private void setupCoverArt(View header) { - setupCoverArtImpl((RecyclingImageView) header.findViewById(R.id.select_album_art)); - } - private void setupCoverArtImpl(RecyclingImageView coverArtView) { - final ImageLoader imageLoader = getImageLoader(); + return header; + } - if(entries.size() > 0) { - coverArtRep = null; - this.coverArtView = coverArtView; - for (int i = 0; (i < 3) && (coverArtRep == null || coverArtRep.getCoverArt() == null); i++) { - coverArtRep = entries.get(random.nextInt(entries.size())); - } + private void setupCoverArt(View header) { + setupCoverArtImpl((RecyclingImageView) header.findViewById(R.id.select_album_art)); + } + private void setupCoverArtImpl(RecyclingImageView coverArtView) { + final ImageLoader imageLoader = getImageLoader(); - coverArtView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - if (coverArtRep == null || coverArtRep.getCoverArt() == null) { - return; - } + if(entries.size() > 0) { + coverArtRep = null; + this.coverArtView = coverArtView; + for (int i = 0; (i < 3) && (coverArtRep == null || coverArtRep.getCoverArt() == null); i++) { + coverArtRep = entries.get(random.nextInt(entries.size())); + } - AlertDialog.Builder builder = new AlertDialog.Builder(context); - ImageView fullScreenView = new ImageView(context); - imageLoader.loadImage(fullScreenView, coverArtRep, true, true); - builder.setCancelable(true); + coverArtView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (coverArtRep == null || coverArtRep.getCoverArt() == null) { + return; + } - AlertDialog imageDialog = builder.create(); - // Set view here with unecessary 0's to remove top/bottom border - imageDialog.setView(fullScreenView, 0, 0, 0, 0); - imageDialog.show(); - } - }); - synchronized (coverArtRep) { - coverArtId = coverArtRep.getCoverArt(); - updateCoverArtTask = imageLoader.loadImage(coverArtView, coverArtRep, false, true); - } - } + AlertDialog.Builder builder = new AlertDialog.Builder(context); + ImageView fullScreenView = new ImageView(context); + imageLoader.loadImage(fullScreenView, coverArtRep, true, true); + builder.setCancelable(true); - coverArtView.setOnInvalidated(new RecyclingImageView.OnInvalidated() { - @Override - public void onInvalidated(RecyclingImageView imageView) { - setupCoverArtImpl(imageView); - } - }); - } - private void setupTextDisplay(final View header) { - final TextView titleView = (TextView) header.findViewById(R.id.select_album_title); - if(playlistName != null) { - titleView.setText(playlistName); - } else if(name != null) { - titleView.setText(name); - } + AlertDialog imageDialog = builder.create(); + // Set view here with unecessary 0's to remove top/bottom border + imageDialog.setView(fullScreenView, 0, 0, 0, 0); + imageDialog.show(); + } + }); + synchronized (coverArtRep) { + coverArtId = coverArtRep.getCoverArt(); + updateCoverArtTask = imageLoader.loadImage(coverArtView, coverArtRep, false, true); + } + } - int songCount = 0; + coverArtView.setOnInvalidated(new RecyclingImageView.OnInvalidated() { + @Override + public void onInvalidated(RecyclingImageView imageView) { + setupCoverArtImpl(imageView); + } + }); + } + private void setupTextDisplay(final View header) { + final TextView titleView = (TextView) header.findViewById(R.id.select_album_title); + if(playlistName != null) { + titleView.setText(playlistName); + } else if(name != null) { + titleView.setText(name); + } - Set artists = new HashSet(); - Set years = new HashSet(); - Integer totalDuration = 0; - for (Entry entry : entries) { - if (!entry.isDirectory()) { - songCount++; - if (entry.getArtist() != null) { - artists.add(entry.getArtist()); - } - if(entry.getYear() != null) { - years.add(entry.getYear()); - } - Integer duration = entry.getDuration(); - if(duration != null) { - totalDuration += duration; - } - } - } + int songCount = 0; - final TextView artistView = (TextView) header.findViewById(R.id.select_album_artist); - if (artists.size() == 1) { - String artistText = artists.iterator().next(); - if(years.size() == 1) { - artistText += " - " + years.iterator().next(); - } - artistView.setText(artistText); - artistView.setVisibility(View.VISIBLE); - } else { - artistView.setVisibility(View.GONE); - } + Set artists = new HashSet(); + Set years = new HashSet(); + Integer totalDuration = 0; + for (Entry entry : entries) { + if (!entry.isDirectory()) { + songCount++; + if (entry.getArtist() != null) { + artists.add(entry.getArtist()); + } + if(entry.getYear() != null) { + years.add(entry.getYear()); + } + Integer duration = entry.getDuration(); + if(duration != null) { + totalDuration += duration; + } + } + } - TextView songCountView = (TextView) header.findViewById(R.id.select_album_song_count); - TextView songLengthView = (TextView) header.findViewById(R.id.select_album_song_length); + final TextView artistView = (TextView) header.findViewById(R.id.select_album_artist); + if (artists.size() == 1) { + String artistText = artists.iterator().next(); + if(years.size() == 1) { + artistText += " - " + years.iterator().next(); + } + artistView.setText(artistText); + artistView.setVisibility(View.VISIBLE); + } else { + artistView.setVisibility(View.GONE); + } + + TextView songCountView = (TextView) header.findViewById(R.id.select_album_song_count); + TextView songLengthView = (TextView) header.findViewById(R.id.select_album_song_length); String s = context.getResources().getQuantityString(R.plurals.select_album_n_songs, songCount, songCount); songCountView.setText(s.toUpperCase()); songLengthView.setText(Util.formatDuration(totalDuration)); - } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/SelectGenreFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/SelectGenreFragment.java index cf4ee86..290cfc4 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/SelectGenreFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/SelectGenreFragment.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.fragments; @@ -32,46 +32,46 @@ import net.nullsum.audinaut.view.UpdateView; import java.util.List; public class SelectGenreFragment extends SelectRecyclerFragment { - private static final String TAG = SelectGenreFragment.class.getSimpleName(); + private static final String TAG = SelectGenreFragment.class.getSimpleName(); - @Override - public int getOptionsMenu() { - return R.menu.empty; - } + @Override + public int getOptionsMenu() { + return R.menu.empty; + } - @Override - public SectionAdapter getAdapter(List objs) { - return new GenreAdapter(context, objs, this); - } + @Override + public SectionAdapter getAdapter(List objs) { + return new GenreAdapter(context, objs, this); + } - @Override - public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { - return musicService.getGenres(refresh, context, listener); - } + @Override + public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { + return musicService.getGenres(refresh, context, listener); + } - @Override - public int getTitleResource() { - return R.string.main_albums_genres; - } - - @Override - public void onItemClicked(UpdateView updateView, Genre genre) { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, "genres"); - args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20); - args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0); - args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA, genre.getName()); - fragment.setArguments(args); + @Override + public int getTitleResource() { + return R.string.main_albums_genres; + } - replaceFragment(fragment); - } + @Override + public void onItemClicked(UpdateView updateView, Genre genre) { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, "genres"); + args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20); + args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0); + args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA, genre.getName()); + fragment.setArguments(args); - @Override - public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Genre item) {} + replaceFragment(fragment); + } - @Override - public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Genre item) { - return false; - } + @Override + public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Genre item) {} + + @Override + public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Genre item) { + return false; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/SelectPlaylistFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/SelectPlaylistFragment.java index 757dc81..5b0117b 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/SelectPlaylistFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/SelectPlaylistFragment.java @@ -36,311 +36,311 @@ import java.util.Arrays; import java.util.List; public class SelectPlaylistFragment extends SelectRecyclerFragment { - private static final String TAG = SelectPlaylistFragment.class.getSimpleName(); + private static final String TAG = SelectPlaylistFragment.class.getSimpleName(); - @Override - public void onCreate(Bundle bundle) { - super.onCreate(bundle); - if (Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_LARGE_ALBUM_ART, true)) { - largeAlbums = true; - } - } + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); + if (Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_LARGE_ALBUM_ART, true)) { + largeAlbums = true; + } + } - @Override - public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Playlist playlist) { - if (Util.isOffline(context)) { - menuInflater.inflate(R.menu.select_playlist_context_offline, menu); - } - else { - menuInflater.inflate(R.menu.select_playlist_context, menu); + @Override + public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, Playlist playlist) { + if (Util.isOffline(context)) { + menuInflater.inflate(R.menu.select_playlist_context_offline, menu); + } + else { + menuInflater.inflate(R.menu.select_playlist_context, menu); - if(playlist.getPublic() != null && playlist.getPublic() == true && playlist.getId().indexOf(".m3u") == -1 && !UserUtil.getCurrentUsername(context).equals(playlist.getOwner())) { - menu.removeItem(R.id.playlist_update_info); - menu.removeItem(R.id.playlist_menu_delete); - } - } + if(playlist.getPublic() != null && playlist.getPublic() == true && playlist.getId().indexOf(".m3u") == -1 && !UserUtil.getCurrentUsername(context).equals(playlist.getOwner())) { + menu.removeItem(R.id.playlist_update_info); + menu.removeItem(R.id.playlist_menu_delete); + } + } - recreateContextMenu(menu); - } + recreateContextMenu(menu); + } - @Override - public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Playlist playlist) { - SubsonicFragment fragment; - Bundle args; - FragmentTransaction trans; + @Override + public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, Playlist playlist) { + SubsonicFragment fragment; + Bundle args; + FragmentTransaction trans; - switch (menuItem.getItemId()) { - case R.id.playlist_menu_download: - downloadPlaylist(playlist.getId(), playlist.getName(), false, true, false, false, true); - break; - case R.id.playlist_menu_play_now: - fragment = new SelectDirectoryFragment(); - args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID, playlist.getId()); - args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME, playlist.getName()); - args.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true); - fragment.setArguments(args); + switch (menuItem.getItemId()) { + case R.id.playlist_menu_download: + downloadPlaylist(playlist.getId(), playlist.getName(), false, true, false, false, true); + break; + case R.id.playlist_menu_play_now: + fragment = new SelectDirectoryFragment(); + args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID, playlist.getId()); + args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME, playlist.getName()); + args.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true); + fragment.setArguments(args); - replaceFragment(fragment); - break; - case R.id.playlist_menu_play_shuffled: - fragment = new SelectDirectoryFragment(); - args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID, playlist.getId()); - args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME, playlist.getName()); - args.putBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, true); - args.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true); - fragment.setArguments(args); + replaceFragment(fragment); + break; + case R.id.playlist_menu_play_shuffled: + fragment = new SelectDirectoryFragment(); + args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID, playlist.getId()); + args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME, playlist.getName()); + args.putBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE, true); + args.putBoolean(Constants.INTENT_EXTRA_NAME_AUTOPLAY, true); + fragment.setArguments(args); - replaceFragment(fragment); - break; - case R.id.playlist_menu_delete: - deletePlaylist(playlist); - break; - case R.id.playlist_info: - displayPlaylistInfo(playlist); - break; - case R.id.playlist_update_info: - updatePlaylistInfo(playlist); - break; - } + replaceFragment(fragment); + break; + case R.id.playlist_menu_delete: + deletePlaylist(playlist); + break; + case R.id.playlist_info: + displayPlaylistInfo(playlist); + break; + case R.id.playlist_update_info: + updatePlaylistInfo(playlist); + break; + } - return false; - } + return false; + } - @Override - public int getOptionsMenu() { - return R.menu.abstract_top_menu; - } + @Override + public int getOptionsMenu() { + return R.menu.abstract_top_menu; + } - @Override - public SectionAdapter getAdapter(List playlists) { - List mine = new ArrayList<>(); + @Override + public SectionAdapter getAdapter(List playlists) { + List mine = new ArrayList<>(); - String currentUsername = UserUtil.getCurrentUsername(context); - for(Playlist playlist: playlists) { - if(playlist.getOwner() == null || playlist.getOwner().equals(currentUsername)) { - mine.add(playlist); - } - } + String currentUsername = UserUtil.getCurrentUsername(context); + for(Playlist playlist: playlists) { + if(playlist.getOwner() == null || playlist.getOwner().equals(currentUsername)) { + mine.add(playlist); + } + } return new PlaylistAdapter(context, playlists, getImageLoader(), largeAlbums, this); - } + } - @Override - public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { - List playlists = musicService.getPlaylists(refresh, context, listener); - if(!Util.isOffline(context) && refresh) { - new CacheCleaner(context, getDownloadService()).cleanPlaylists(playlists); - } - return playlists; - } + @Override + public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { + List playlists = musicService.getPlaylists(refresh, context, listener); + if(!Util.isOffline(context) && refresh) { + new CacheCleaner(context, getDownloadService()).cleanPlaylists(playlists); + } + return playlists; + } - @Override - public int getTitleResource() { - return R.string.playlist_label; - } + @Override + public int getTitleResource() { + return R.string.playlist_label; + } - @Override - public void onItemClicked(UpdateView updateView, Playlist playlist) { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID, playlist.getId()); - args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME, playlist.getName()); - if((playlist.getOwner() != null && playlist.getOwner().equals(UserUtil.getCurrentUsername(context)) || playlist.getId().indexOf(".m3u") != -1)) { - args.putBoolean(Constants.INTENT_EXTRA_NAME_PLAYLIST_OWNER, true); - } - fragment.setArguments(args); + @Override + public void onItemClicked(UpdateView updateView, Playlist playlist) { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_ID, playlist.getId()); + args.putString(Constants.INTENT_EXTRA_NAME_PLAYLIST_NAME, playlist.getName()); + if((playlist.getOwner() != null && playlist.getOwner().equals(UserUtil.getCurrentUsername(context)) || playlist.getId().indexOf(".m3u") != -1)) { + args.putBoolean(Constants.INTENT_EXTRA_NAME_PLAYLIST_OWNER, true); + } + fragment.setArguments(args); - replaceFragment(fragment); - } + replaceFragment(fragment); + } - @Override - public void onFinishRefresh() { - Bundle args = getArguments(); - if(args != null) { - String playlistId = args.getString(Constants.INTENT_EXTRA_NAME_ID, null); - if (playlistId != null && objects != null) { - for (Playlist playlist : objects) { - if (playlistId.equals(playlist.getId())) { - onItemClicked(null, playlist); - break; - } - } - } - } - } + @Override + public void onFinishRefresh() { + Bundle args = getArguments(); + if(args != null) { + String playlistId = args.getString(Constants.INTENT_EXTRA_NAME_ID, null); + if (playlistId != null && objects != null) { + for (Playlist playlist : objects) { + if (playlistId.equals(playlist.getId())) { + onItemClicked(null, playlist); + break; + } + } + } + } + } - private void deletePlaylist(final Playlist playlist) { - Util.confirmDialog(context, R.string.common_delete, playlist.getName(), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - new LoadingTask(context, false) { - @Override - protected Void doInBackground() throws Throwable { - MusicService musicService = MusicServiceFactory.getMusicService(context); - musicService.deletePlaylist(playlist.getId(), context, null); - SyncUtil.removeSyncedPlaylist(context, playlist.getId()); - return null; - } + private void deletePlaylist(final Playlist playlist) { + Util.confirmDialog(context, R.string.common_delete, playlist.getName(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + new LoadingTask(context, false) { + @Override + protected Void doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + musicService.deletePlaylist(playlist.getId(), context, null); + SyncUtil.removeSyncedPlaylist(context, playlist.getId()); + return null; + } - @Override - protected void done(Void result) { - adapter.removeItem(playlist); - Util.toast(context, context.getResources().getString(R.string.menu_deleted_playlist, playlist.getName())); - } + @Override + protected void done(Void result) { + adapter.removeItem(playlist); + Util.toast(context, context.getResources().getString(R.string.menu_deleted_playlist, playlist.getName())); + } - @Override - protected void error(Throwable error) { - String msg; - if (error instanceof OfflineException) { - msg = getErrorMessage(error); - } else { - msg = context.getResources().getString(R.string.menu_deleted_playlist_error, playlist.getName()) + " " + getErrorMessage(error); - } + @Override + protected void error(Throwable error) { + String msg; + if (error instanceof OfflineException) { + msg = getErrorMessage(error); + } else { + msg = context.getResources().getString(R.string.menu_deleted_playlist_error, playlist.getName()) + " " + getErrorMessage(error); + } - Util.toast(context, msg, false); - } - }.execute(); - } - }); - } + Util.toast(context, msg, false); + } + }.execute(); + } + }); + } - private void displayPlaylistInfo(final Playlist playlist) { - List headers = new ArrayList<>(); - List details = new ArrayList<>(); + private void displayPlaylistInfo(final Playlist playlist) { + List headers = new ArrayList<>(); + List details = new ArrayList<>(); - headers.add(R.string.details_title); - details.add(playlist.getName()); + headers.add(R.string.details_title); + details.add(playlist.getName()); - if(playlist.getOwner() != null) { - headers.add(R.string.details_owner); - details.add(playlist.getOwner()); - } + if(playlist.getOwner() != null) { + headers.add(R.string.details_owner); + details.add(playlist.getOwner()); + } - if(playlist.getComment() != null) { - headers.add(R.string.details_comments); - details.add(playlist.getComment()); - } + if(playlist.getComment() != null) { + headers.add(R.string.details_comments); + details.add(playlist.getComment()); + } - headers.add(R.string.details_song_count); - details.add(playlist.getSongCount()); + headers.add(R.string.details_song_count); + details.add(playlist.getSongCount()); - if(playlist.getDuration() != null) { - headers.add(R.string.details_length); - details.add(Util.formatDuration(playlist.getDuration())); - } + if(playlist.getDuration() != null) { + headers.add(R.string.details_length); + details.add(Util.formatDuration(playlist.getDuration())); + } - if(playlist.getPublic() != null) { - headers.add(R.string.details_public); - details.add(Util.formatBoolean(context, playlist.getPublic())); - } + if(playlist.getPublic() != null) { + headers.add(R.string.details_public); + details.add(Util.formatBoolean(context, playlist.getPublic())); + } - if(playlist.getCreated() != null) { - headers.add(R.string.details_created); + if(playlist.getCreated() != null) { + headers.add(R.string.details_created); DateFormat dateFormat = DateFormat.getDateInstance(); - details.add(dateFormat.format(playlist.getCreated())); - } - if(playlist.getChanged() != null) { - headers.add(R.string.details_updated); + details.add(dateFormat.format(playlist.getCreated())); + } + if(playlist.getChanged() != null) { + headers.add(R.string.details_updated); DateFormat dateFormat = DateFormat.getDateInstance(); - details.add(dateFormat.format(playlist.getChanged())); - } + details.add(dateFormat.format(playlist.getChanged())); + } - Util.showDetailsDialog(context, R.string.details_title_playlist, headers, details); - } + Util.showDetailsDialog(context, R.string.details_title_playlist, headers, details); + } - private void updatePlaylistInfo(final Playlist playlist) { - View dialogView = context.getLayoutInflater().inflate(R.layout.update_playlist, null); - final EditText nameBox = (EditText)dialogView.findViewById(R.id.get_playlist_name); - final EditText commentBox = (EditText)dialogView.findViewById(R.id.get_playlist_comment); - final CheckBox publicBox = (CheckBox)dialogView.findViewById(R.id.get_playlist_public); + private void updatePlaylistInfo(final Playlist playlist) { + View dialogView = context.getLayoutInflater().inflate(R.layout.update_playlist, null); + final EditText nameBox = (EditText)dialogView.findViewById(R.id.get_playlist_name); + final EditText commentBox = (EditText)dialogView.findViewById(R.id.get_playlist_comment); + final CheckBox publicBox = (CheckBox)dialogView.findViewById(R.id.get_playlist_public); - nameBox.setText(playlist.getName()); - commentBox.setText(playlist.getComment()); - Boolean pub = playlist.getPublic(); - if(pub == null) { - publicBox.setEnabled(false); - } else { - publicBox.setChecked(pub); - } + nameBox.setText(playlist.getName()); + commentBox.setText(playlist.getComment()); + Boolean pub = playlist.getPublic(); + if(pub == null) { + publicBox.setEnabled(false); + } else { + publicBox.setChecked(pub); + } - new AlertDialog.Builder(context) - .setIcon(android.R.drawable.ic_dialog_alert) - .setTitle(R.string.playlist_update_info) - .setView(dialogView) - .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - new LoadingTask(context, false) { - @Override - protected Void doInBackground() throws Throwable { - String name = nameBox.getText().toString(); - String comment = commentBox.getText().toString(); - boolean isPublic = publicBox.isChecked(); + new AlertDialog.Builder(context) + .setIcon(android.R.drawable.ic_dialog_alert) + .setTitle(R.string.playlist_update_info) + .setView(dialogView) + .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + new LoadingTask(context, false) { + @Override + protected Void doInBackground() throws Throwable { + String name = nameBox.getText().toString(); + String comment = commentBox.getText().toString(); + boolean isPublic = publicBox.isChecked(); - MusicService musicService = MusicServiceFactory.getMusicService(context); - musicService.updatePlaylist(playlist.getId(), name, comment, isPublic, context, null); + MusicService musicService = MusicServiceFactory.getMusicService(context); + musicService.updatePlaylist(playlist.getId(), name, comment, isPublic, context, null); - playlist.setName(name); - playlist.setComment(comment); - playlist.setPublic(isPublic); + playlist.setName(name); + playlist.setComment(comment); + playlist.setPublic(isPublic); - return null; - } + return null; + } - @Override - protected void done(Void result) { - Util.toast(context, context.getResources().getString(R.string.playlist_updated_info, playlist.getName())); - } + @Override + protected void done(Void result) { + Util.toast(context, context.getResources().getString(R.string.playlist_updated_info, playlist.getName())); + } - @Override - protected void error(Throwable error) { - String msg; - if (error instanceof OfflineException) { - msg = getErrorMessage(error); - } else { - msg = context.getResources().getString(R.string.playlist_updated_info_error, playlist.getName()) + " " + getErrorMessage(error); - } + @Override + protected void error(Throwable error) { + String msg; + if (error instanceof OfflineException) { + msg = getErrorMessage(error); + } else { + msg = context.getResources().getString(R.string.playlist_updated_info_error, playlist.getName()) + " " + getErrorMessage(error); + } - Util.toast(context, msg, false); - } - }.execute(); - } + Util.toast(context, msg, false); + } + }.execute(); + } - }) - .setNegativeButton(R.string.common_cancel, null) - .show(); - } + }) + .setNegativeButton(R.string.common_cancel, null) + .show(); + } - private void syncPlaylist(Playlist playlist) { - SyncUtil.addSyncedPlaylist(context, playlist.getId()); - downloadPlaylist(playlist.getId(), playlist.getName(), true, true, false, false, true); - } + private void syncPlaylist(Playlist playlist) { + SyncUtil.addSyncedPlaylist(context, playlist.getId()); + downloadPlaylist(playlist.getId(), playlist.getName(), true, true, false, false, true); + } - private void stopSyncPlaylist(final Playlist playlist) { - SyncUtil.removeSyncedPlaylist(context, playlist.getId()); + private void stopSyncPlaylist(final Playlist playlist) { + SyncUtil.removeSyncedPlaylist(context, playlist.getId()); - new LoadingTask(context, false) { - @Override - protected Void doInBackground() throws Throwable { - // Unpin all of the songs in playlist - MusicService musicService = MusicServiceFactory.getMusicService(context); - MusicDirectory root = musicService.getPlaylist(true, playlist.getId(), playlist.getName(), context, this); - for(MusicDirectory.Entry entry: root.getChildren()) { - DownloadFile file = new DownloadFile(context, entry, false); - file.unpin(); - } + new LoadingTask(context, false) { + @Override + protected Void doInBackground() throws Throwable { + // Unpin all of the songs in playlist + MusicService musicService = MusicServiceFactory.getMusicService(context); + MusicDirectory root = musicService.getPlaylist(true, playlist.getId(), playlist.getName(), context, this); + for(MusicDirectory.Entry entry: root.getChildren()) { + DownloadFile file = new DownloadFile(context, entry, false); + file.unpin(); + } - return null; - } + return null; + } - @Override - protected void done(Void result) { + @Override + protected void done(Void result) { - } - }.execute(); - } + } + }.execute(); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/SelectRecyclerFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/SelectRecyclerFragment.java index 2af0bbf..8f1dbdb 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/SelectRecyclerFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/SelectRecyclerFragment.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.fragments; @@ -46,174 +46,174 @@ import net.nullsum.audinaut.util.TabBackgroundTask; import net.nullsum.audinaut.view.FastScroller; public abstract class SelectRecyclerFragment extends SubsonicFragment implements SectionAdapter.OnItemClickedListener { - private static final String TAG = SelectRecyclerFragment.class.getSimpleName(); - protected RecyclerView recyclerView; - protected FastScroller fastScroller; - protected SectionAdapter adapter; - protected UpdateTask currentTask; - protected List objects; - protected boolean serialize = true; - protected boolean largeAlbums = false; - protected boolean pullToRefresh = true; - protected boolean backgroundUpdate = true; + private static final String TAG = SelectRecyclerFragment.class.getSimpleName(); + protected RecyclerView recyclerView; + protected FastScroller fastScroller; + protected SectionAdapter adapter; + protected UpdateTask currentTask; + protected List objects; + protected boolean serialize = true; + protected boolean largeAlbums = false; + protected boolean pullToRefresh = true; + protected boolean backgroundUpdate = true; - @Override - public void onCreate(Bundle bundle) { - super.onCreate(bundle); + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); - if(bundle != null && serialize) { - objects = (List) bundle.getSerializable(Constants.FRAGMENT_LIST); - } - } + if(bundle != null && serialize) { + objects = (List) bundle.getSerializable(Constants.FRAGMENT_LIST); + } + } - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - if(serialize) { - outState.putSerializable(Constants.FRAGMENT_LIST, (Serializable) objects); - } - } + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + if(serialize) { + outState.putSerializable(Constants.FRAGMENT_LIST, (Serializable) objects); + } + } - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { - rootView = inflater.inflate(R.layout.abstract_recycler_fragment, container, false); + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) { + rootView = inflater.inflate(R.layout.abstract_recycler_fragment, container, false); - refreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout); - refreshLayout.setOnRefreshListener(this); + refreshLayout = (SwipeRefreshLayout) rootView.findViewById(R.id.refresh_layout); + refreshLayout.setOnRefreshListener(this); - recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_recycler); - fastScroller = (FastScroller) rootView.findViewById(R.id.fragment_fast_scroller); - setupLayoutManager(); + recyclerView = (RecyclerView) rootView.findViewById(R.id.fragment_recycler); + fastScroller = (FastScroller) rootView.findViewById(R.id.fragment_fast_scroller); + setupLayoutManager(); - if(pullToRefresh) { - setupScrollList(recyclerView); - } else { - refreshLayout.setEnabled(false); - } + if(pullToRefresh) { + setupScrollList(recyclerView); + } else { + refreshLayout.setEnabled(false); + } - if(objects == null) { - refresh(false); - } else { - recyclerView.setAdapter(adapter = getAdapter(objects)); - } + if(objects == null) { + refresh(false); + } else { + recyclerView.setAdapter(adapter = getAdapter(objects)); + } - return rootView; - } - - @Override - public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { - if(!primaryFragment) { - return; - } + return rootView; + } - menuInflater.inflate(getOptionsMenu(), menu); - onFinishSetupOptionsMenu(menu); - } - - @Override - public boolean onOptionsItemSelected(MenuItem item) { - return super.onOptionsItemSelected(item); - } + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) { + if(!primaryFragment) { + return; + } - @Override - public void setIsOnlyVisible(boolean isOnlyVisible) { - boolean update = this.isOnlyVisible != isOnlyVisible; - super.setIsOnlyVisible(isOnlyVisible); - if(update && adapter != null) { - RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); - if(layoutManager instanceof GridLayoutManager) { - ((GridLayoutManager) layoutManager).setSpanCount(getRecyclerColumnCount()); - } - } - } + menuInflater.inflate(getOptionsMenu(), menu); + onFinishSetupOptionsMenu(menu); + } - @Override - protected void refresh(final boolean refresh) { - int titleRes = getTitleResource(); - if(titleRes != 0) { - setTitle(getTitleResource()); - } - if(backgroundUpdate) { - recyclerView.setVisibility(View.GONE); - } - - // Cancel current running task before starting another one - if(currentTask != null) { - currentTask.cancel(); - } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + return super.onOptionsItemSelected(item); + } - currentTask = new UpdateTask(this, refresh); + @Override + public void setIsOnlyVisible(boolean isOnlyVisible) { + boolean update = this.isOnlyVisible != isOnlyVisible; + super.setIsOnlyVisible(isOnlyVisible); + if(update && adapter != null) { + RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); + if(layoutManager instanceof GridLayoutManager) { + ((GridLayoutManager) layoutManager).setSpanCount(getRecyclerColumnCount()); + } + } + } - if(backgroundUpdate) { - currentTask.execute(); - } else { - objects = new ArrayList(); + @Override + protected void refresh(final boolean refresh) { + int titleRes = getTitleResource(); + if(titleRes != 0) { + setTitle(getTitleResource()); + } + if(backgroundUpdate) { + recyclerView.setVisibility(View.GONE); + } - try { - objects = getObjects(null, refresh, null); - } catch (Exception x) { - Log.e(TAG, "Failed to load", x); - } + // Cancel current running task before starting another one + if(currentTask != null) { + currentTask.cancel(); + } - currentTask.done(objects); - } - } + currentTask = new UpdateTask(this, refresh); - public SectionAdapter getCurrentAdapter() { - return adapter; - } + if(backgroundUpdate) { + currentTask.execute(); + } else { + objects = new ArrayList(); - private void setupLayoutManager() { - setupLayoutManager(recyclerView, largeAlbums); - } + try { + objects = getObjects(null, refresh, null); + } catch (Exception x) { + Log.e(TAG, "Failed to load", x); + } - public abstract int getOptionsMenu(); - public abstract SectionAdapter getAdapter(List objs); - public abstract List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception; - public abstract int getTitleResource(); - - public void onFinishRefresh() { - - } + currentTask.done(objects); + } + } - private class UpdateTask extends TabBackgroundTask> { - private boolean refresh; + public SectionAdapter getCurrentAdapter() { + return adapter; + } - public UpdateTask(SubsonicFragment fragment, boolean refresh) { - super(fragment); - this.refresh = refresh; - } + private void setupLayoutManager() { + setupLayoutManager(recyclerView, largeAlbums); + } - @Override - public List doInBackground() throws Exception { - MusicService musicService = MusicServiceFactory.getMusicService(context); + public abstract int getOptionsMenu(); + public abstract SectionAdapter getAdapter(List objs); + public abstract List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception; + public abstract int getTitleResource(); - objects = new ArrayList(); + public void onFinishRefresh() { - try { - objects = getObjects(musicService, refresh, this); - } catch (Exception x) { - Log.e(TAG, "Failed to load", x); - } + } - return objects; - } + private class UpdateTask extends TabBackgroundTask> { + private boolean refresh; - @Override - public void done(List result) { - if (result != null && !result.isEmpty()) { - recyclerView.setAdapter(adapter = getAdapter(result)); - if(!fastScroller.isAttached()) { - fastScroller.attachRecyclerView(recyclerView); - } + public UpdateTask(SubsonicFragment fragment, boolean refresh) { + super(fragment); + this.refresh = refresh; + } - onFinishRefresh(); - recyclerView.setVisibility(View.VISIBLE); - } else { - setEmpty(true); - } + @Override + public List doInBackground() throws Exception { + MusicService musicService = MusicServiceFactory.getMusicService(context); - currentTask = null; - } - } + objects = new ArrayList(); + + try { + objects = getObjects(musicService, refresh, this); + } catch (Exception x) { + Log.e(TAG, "Failed to load", x); + } + + return objects; + } + + @Override + public void done(List result) { + if (result != null && !result.isEmpty()) { + recyclerView.setAdapter(adapter = getAdapter(result)); + if(!fastScroller.isAttached()) { + fastScroller.attachRecyclerView(recyclerView); + } + + onFinishRefresh(); + recyclerView.setVisibility(View.VISIBLE); + } else { + setEmpty(true); + } + + currentTask = null; + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/SelectYearFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/SelectYearFragment.java index e502f55..57e023c 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/SelectYearFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/SelectYearFragment.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.fragments; @@ -33,56 +33,56 @@ import net.nullsum.audinaut.view.UpdateView; public class SelectYearFragment extends SelectRecyclerFragment { - public SelectYearFragment() { - super(); - pullToRefresh = false; - serialize = false; - backgroundUpdate = false; - } + public SelectYearFragment() { + super(); + pullToRefresh = false; + serialize = false; + backgroundUpdate = false; + } - @Override - public int getOptionsMenu() { - return R.menu.empty; - } + @Override + public int getOptionsMenu() { + return R.menu.empty; + } - @Override - public SectionAdapter getAdapter(List objs) { - return new BasicListAdapter(context, objs, this); - } + @Override + public SectionAdapter getAdapter(List objs) { + return new BasicListAdapter(context, objs, this); + } - @Override - public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { - List decades = new ArrayList<>(); - for(int i = 2010; i >= 1800; i -= 10) { - decades.add(String.valueOf(i)); - } + @Override + public List getObjects(MusicService musicService, boolean refresh, ProgressListener listener) throws Exception { + List decades = new ArrayList<>(); + for(int i = 2010; i >= 1800; i -= 10) { + decades.add(String.valueOf(i)); + } - return decades; - } + return decades; + } - @Override - public int getTitleResource() { - return R.string.main_albums_year; - } + @Override + public int getTitleResource() { + return R.string.main_albums_year; + } - @Override - public void onItemClicked(UpdateView updateView, String decade) { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, "years"); - args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20); - args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0); - args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA, decade); - fragment.setArguments(args); + @Override + public void onItemClicked(UpdateView updateView, String decade) { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_TYPE, "years"); + args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_SIZE, 20); + args.putInt(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET, 0); + args.putString(Constants.INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA, decade); + fragment.setArguments(args); - replaceFragment(fragment); - } + replaceFragment(fragment); + } - @Override - public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, String item) {} + @Override + public void onCreateContextMenu(Menu menu, MenuInflater menuInflater, UpdateView updateView, String item) {} - @Override - public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, String item) { - return false; - } + @Override + public boolean onContextItemSelected(MenuItem menuItem, UpdateView updateView, String item) { + return false; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/SettingsFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/SettingsFragment.java index de2cbcb..6f03da5 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/SettingsFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/SettingsFragment.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.fragments; @@ -60,747 +60,747 @@ import net.nullsum.audinaut.view.CacheLocationPreference; import net.nullsum.audinaut.view.ErrorDialog; public class SettingsFragment extends PreferenceCompatFragment implements SharedPreferences.OnSharedPreferenceChangeListener { - private final static String TAG = SettingsFragment.class.getSimpleName(); + private final static String TAG = SettingsFragment.class.getSimpleName(); - private final Map serverSettings = new LinkedHashMap(); - private boolean testingConnection; - private ListPreference theme; - private ListPreference maxBitrateWifi; - private ListPreference maxBitrateMobile; - private ListPreference networkTimeout; - private CacheLocationPreference cacheLocation; - private ListPreference preloadCountWifi; - private ListPreference preloadCountMobile; - private ListPreference keepPlayedCount; - private ListPreference tempLoss; - private ListPreference pauseDisconnect; - private Preference addServerPreference; - private PreferenceCategory serversCategory; - private ListPreference songPressAction; - private ListPreference syncInterval; - private CheckBoxPreference syncEnabled; - private CheckBoxPreference syncWifi; - private CheckBoxPreference syncNotification; - private CheckBoxPreference syncMostRecent; - private CheckBoxPreference replayGain; - private ListPreference replayGainType; - private Preference replayGainBump; - private Preference replayGainUntagged; - private String internalSSID; - private String internalSSIDDisplay; - private EditTextPreference cacheSize; + private final Map serverSettings = new LinkedHashMap(); + private boolean testingConnection; + private ListPreference theme; + private ListPreference maxBitrateWifi; + private ListPreference maxBitrateMobile; + private ListPreference networkTimeout; + private CacheLocationPreference cacheLocation; + private ListPreference preloadCountWifi; + private ListPreference preloadCountMobile; + private ListPreference keepPlayedCount; + private ListPreference tempLoss; + private ListPreference pauseDisconnect; + private Preference addServerPreference; + private PreferenceCategory serversCategory; + private ListPreference songPressAction; + private ListPreference syncInterval; + private CheckBoxPreference syncEnabled; + private CheckBoxPreference syncWifi; + private CheckBoxPreference syncNotification; + private CheckBoxPreference syncMostRecent; + private CheckBoxPreference replayGain; + private ListPreference replayGainType; + private Preference replayGainBump; + private Preference replayGainUntagged; + private String internalSSID; + private String internalSSIDDisplay; + private EditTextPreference cacheSize; - private int serverCount = 3; - private SharedPreferences settings; - private DecimalFormat megabyteFromat; + private int serverCount = 3; + private SharedPreferences settings; + private DecimalFormat megabyteFromat; - @Override - public void onCreate(Bundle bundle) { - super.onCreate(bundle); + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); - int instance = this.getArguments().getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, -1); - if (instance != -1) { - PreferenceScreen preferenceScreen = expandServer(instance); - setPreferenceScreen(preferenceScreen); + int instance = this.getArguments().getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, -1); + if (instance != -1) { + PreferenceScreen preferenceScreen = expandServer(instance); + setPreferenceScreen(preferenceScreen); - serverSettings.put(Integer.toString(instance), new ServerSettings(instance)); - onInitPreferences(preferenceScreen); - } - } + serverSettings.put(Integer.toString(instance), new ServerSettings(instance)); + onInitPreferences(preferenceScreen); + } + } - @Override - public void onDestroy() { - super.onDestroy(); + @Override + public void onDestroy() { + super.onDestroy(); - SharedPreferences prefs = Util.getPreferences(context); - prefs.unregisterOnSharedPreferenceChangeListener(this); - } + SharedPreferences prefs = Util.getPreferences(context); + prefs.unregisterOnSharedPreferenceChangeListener(this); + } - @Override - protected void onStartNewFragment(String name) { - SettingsFragment newFragment = new SettingsFragment(); - Bundle args = new Bundle(); + @Override + protected void onStartNewFragment(String name) { + SettingsFragment newFragment = new SettingsFragment(); + Bundle args = new Bundle(); - int xml = 0; - if("appearance".equals(name)) { - xml = R.xml.settings_appearance; - } else if("cache".equals(name)) { - xml = R.xml.settings_cache; - } else if("playback".equals(name)) { - xml = R.xml.settings_playback; - } else if("servers".equals(name)) { - xml = R.xml.settings_servers; + int xml = 0; + if("appearance".equals(name)) { + xml = R.xml.settings_appearance; + } else if("cache".equals(name)) { + xml = R.xml.settings_cache; + } else if("playback".equals(name)) { + xml = R.xml.settings_playback; + } else if("servers".equals(name)) { + xml = R.xml.settings_servers; } - if(xml != 0) { - args.putInt(Constants.INTENT_EXTRA_FRAGMENT_TYPE, xml); - newFragment.setArguments(args); - replaceFragment(newFragment); - } - } + if(xml != 0) { + args.putInt(Constants.INTENT_EXTRA_FRAGMENT_TYPE, xml); + newFragment.setArguments(args); + replaceFragment(newFragment); + } + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + // Random error I have no idea how to reproduce + if(sharedPreferences == null) { + return; + } + + update(); + + if (Constants.PREFERENCES_KEY_HIDE_MEDIA.equals(key)) { + setHideMedia(sharedPreferences.getBoolean(key, true)); + } + else if (Constants.PREFERENCES_KEY_MEDIA_BUTTONS.equals(key)) { + setMediaButtonsEnabled(sharedPreferences.getBoolean(key, true)); + } + else if (Constants.PREFERENCES_KEY_CACHE_LOCATION.equals(key)) { + setCacheLocation(sharedPreferences.getString(key, "")); + } + else if(Constants.PREFERENCES_KEY_SYNC_MOST_RECENT.equals(key)) { + SyncUtil.removeMostRecentSyncFiles(context); + } else if(Constants.PREFERENCES_KEY_REPLAY_GAIN.equals(key) || Constants.PREFERENCES_KEY_REPLAY_GAIN_BUMP.equals(key) || Constants.PREFERENCES_KEY_REPLAY_GAIN_UNTAGGED.equals(key)) { + DownloadService downloadService = DownloadService.getInstance(); + if(downloadService != null) { + downloadService.reapplyVolume(); + } + } else if(Constants.PREFERENCES_KEY_START_ON_HEADPHONES.equals(key)) { + Intent serviceIntent = new Intent(); + serviceIntent.setClassName(context.getPackageName(), HeadphoneListenerService.class.getName()); + + if(sharedPreferences.getBoolean(key, false)) { + context.startService(serviceIntent); + } else { + context.stopService(serviceIntent); + } + } + + scheduleBackup(); + } + + @Override + protected void onInitPreferences(PreferenceScreen preferenceScreen) { + this.setTitle(preferenceScreen.getTitle()); + + internalSSID = Util.getSSID(context); + if (internalSSID == null) { + internalSSID = ""; + } + internalSSIDDisplay = context.getResources().getString(R.string.settings_server_local_network_ssid_hint, internalSSID); + + theme = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_THEME); + maxBitrateWifi = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_MAX_BITRATE_WIFI); + maxBitrateMobile = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_MAX_BITRATE_MOBILE); + networkTimeout = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_NETWORK_TIMEOUT); + cacheLocation = (CacheLocationPreference) this.findPreference(Constants.PREFERENCES_KEY_CACHE_LOCATION); + preloadCountWifi = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_PRELOAD_COUNT_WIFI); + preloadCountMobile = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_PRELOAD_COUNT_MOBILE); + keepPlayedCount = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_KEEP_PLAYED_CNT); + tempLoss = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_TEMP_LOSS); + pauseDisconnect = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_PAUSE_DISCONNECT); + serversCategory = (PreferenceCategory) this.findPreference(Constants.PREFERENCES_KEY_SERVER_KEY); + addServerPreference = this.findPreference(Constants.PREFERENCES_KEY_SERVER_ADD); + songPressAction = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_SONG_PRESS_ACTION); + syncInterval = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_SYNC_INTERVAL); + syncEnabled = (CheckBoxPreference) this.findPreference(Constants.PREFERENCES_KEY_SYNC_ENABLED); + syncWifi = (CheckBoxPreference) this.findPreference(Constants.PREFERENCES_KEY_SYNC_WIFI); + syncNotification = (CheckBoxPreference) this.findPreference(Constants.PREFERENCES_KEY_SYNC_NOTIFICATION); + syncMostRecent = (CheckBoxPreference) this.findPreference(Constants.PREFERENCES_KEY_SYNC_MOST_RECENT); + replayGain = (CheckBoxPreference) this.findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN); + replayGainType = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN_TYPE); + replayGainBump = this.findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN_BUMP); + replayGainUntagged = this.findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN_UNTAGGED); + cacheSize = (EditTextPreference) this.findPreference(Constants.PREFERENCES_KEY_CACHE_SIZE); + + settings = Util.getPreferences(context); + serverCount = settings.getInt(Constants.PREFERENCES_KEY_SERVER_COUNT, 1); + + if(cacheSize != null) { + this.findPreference("clearCache").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + Util.confirmDialog(context, R.string.common_delete, R.string.common_confirm_message_cache, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + new LoadingTask(context, false) { + @Override + protected Void doInBackground() throws Throwable { + FileUtil.deleteMusicDirectory(context); + FileUtil.deleteSerializedCache(context); + FileUtil.deleteArtworkCache(context); + return null; + } + + @Override + protected void done(Void result) { + Util.toast(context, R.string.settings_cache_clear_complete); + } + + @Override + protected void error(Throwable error) { + Util.toast(context, getErrorMessage(error), false); + } + }.execute(); + } + }); + return false; + } + }); + } + + if(syncEnabled != null) { + this.findPreference(Constants.PREFERENCES_KEY_SYNC_ENABLED).setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + Boolean syncEnabled = (Boolean) newValue; + + Account account = new Account(Constants.SYNC_ACCOUNT_NAME, Constants.SYNC_ACCOUNT_TYPE); + ContentResolver.setSyncAutomatically(account, Constants.SYNC_ACCOUNT_PLAYLIST_AUTHORITY, syncEnabled); - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - // Random error I have no idea how to reproduce - if(sharedPreferences == null) { - return; - } - - update(); - - if (Constants.PREFERENCES_KEY_HIDE_MEDIA.equals(key)) { - setHideMedia(sharedPreferences.getBoolean(key, true)); - } - else if (Constants.PREFERENCES_KEY_MEDIA_BUTTONS.equals(key)) { - setMediaButtonsEnabled(sharedPreferences.getBoolean(key, true)); - } - else if (Constants.PREFERENCES_KEY_CACHE_LOCATION.equals(key)) { - setCacheLocation(sharedPreferences.getString(key, "")); - } - else if(Constants.PREFERENCES_KEY_SYNC_MOST_RECENT.equals(key)) { - SyncUtil.removeMostRecentSyncFiles(context); - } else if(Constants.PREFERENCES_KEY_REPLAY_GAIN.equals(key) || Constants.PREFERENCES_KEY_REPLAY_GAIN_BUMP.equals(key) || Constants.PREFERENCES_KEY_REPLAY_GAIN_UNTAGGED.equals(key)) { - DownloadService downloadService = DownloadService.getInstance(); - if(downloadService != null) { - downloadService.reapplyVolume(); - } - } else if(Constants.PREFERENCES_KEY_START_ON_HEADPHONES.equals(key)) { - Intent serviceIntent = new Intent(); - serviceIntent.setClassName(context.getPackageName(), HeadphoneListenerService.class.getName()); - - if(sharedPreferences.getBoolean(key, false)) { - context.startService(serviceIntent); - } else { - context.stopService(serviceIntent); - } - } - - scheduleBackup(); - } - - @Override - protected void onInitPreferences(PreferenceScreen preferenceScreen) { - this.setTitle(preferenceScreen.getTitle()); - - internalSSID = Util.getSSID(context); - if (internalSSID == null) { - internalSSID = ""; - } - internalSSIDDisplay = context.getResources().getString(R.string.settings_server_local_network_ssid_hint, internalSSID); - - theme = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_THEME); - maxBitrateWifi = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_MAX_BITRATE_WIFI); - maxBitrateMobile = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_MAX_BITRATE_MOBILE); - networkTimeout = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_NETWORK_TIMEOUT); - cacheLocation = (CacheLocationPreference) this.findPreference(Constants.PREFERENCES_KEY_CACHE_LOCATION); - preloadCountWifi = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_PRELOAD_COUNT_WIFI); - preloadCountMobile = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_PRELOAD_COUNT_MOBILE); - keepPlayedCount = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_KEEP_PLAYED_CNT); - tempLoss = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_TEMP_LOSS); - pauseDisconnect = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_PAUSE_DISCONNECT); - serversCategory = (PreferenceCategory) this.findPreference(Constants.PREFERENCES_KEY_SERVER_KEY); - addServerPreference = this.findPreference(Constants.PREFERENCES_KEY_SERVER_ADD); - songPressAction = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_SONG_PRESS_ACTION); - syncInterval = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_SYNC_INTERVAL); - syncEnabled = (CheckBoxPreference) this.findPreference(Constants.PREFERENCES_KEY_SYNC_ENABLED); - syncWifi = (CheckBoxPreference) this.findPreference(Constants.PREFERENCES_KEY_SYNC_WIFI); - syncNotification = (CheckBoxPreference) this.findPreference(Constants.PREFERENCES_KEY_SYNC_NOTIFICATION); - syncMostRecent = (CheckBoxPreference) this.findPreference(Constants.PREFERENCES_KEY_SYNC_MOST_RECENT); - replayGain = (CheckBoxPreference) this.findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN); - replayGainType = (ListPreference) this.findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN_TYPE); - replayGainBump = this.findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN_BUMP); - replayGainUntagged = this.findPreference(Constants.PREFERENCES_KEY_REPLAY_GAIN_UNTAGGED); - cacheSize = (EditTextPreference) this.findPreference(Constants.PREFERENCES_KEY_CACHE_SIZE); - - settings = Util.getPreferences(context); - serverCount = settings.getInt(Constants.PREFERENCES_KEY_SERVER_COUNT, 1); - - if(cacheSize != null) { - this.findPreference("clearCache").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Util.confirmDialog(context, R.string.common_delete, R.string.common_confirm_message_cache, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - new LoadingTask(context, false) { - @Override - protected Void doInBackground() throws Throwable { - FileUtil.deleteMusicDirectory(context); - FileUtil.deleteSerializedCache(context); - FileUtil.deleteArtworkCache(context); - return null; - } - - @Override - protected void done(Void result) { - Util.toast(context, R.string.settings_cache_clear_complete); - } - - @Override - protected void error(Throwable error) { - Util.toast(context, getErrorMessage(error), false); - } - }.execute(); - } - }); - return false; - } - }); - } - - if(syncEnabled != null) { - this.findPreference(Constants.PREFERENCES_KEY_SYNC_ENABLED).setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - Boolean syncEnabled = (Boolean) newValue; - - Account account = new Account(Constants.SYNC_ACCOUNT_NAME, Constants.SYNC_ACCOUNT_TYPE); - ContentResolver.setSyncAutomatically(account, Constants.SYNC_ACCOUNT_PLAYLIST_AUTHORITY, syncEnabled); - - return true; - } - }); - syncInterval.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - Integer syncInterval = Integer.parseInt(((String) newValue)); - - Account account = new Account(Constants.SYNC_ACCOUNT_NAME, Constants.SYNC_ACCOUNT_TYPE); - ContentResolver.addPeriodicSync(account, Constants.SYNC_ACCOUNT_PLAYLIST_AUTHORITY, new Bundle(), 60L * syncInterval); - - return true; - } - }); - } - - if(serversCategory != null) { - addServerPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - serverCount++; - int instance = serverCount; - serversCategory.addPreference(addServer(serverCount)); - - SharedPreferences.Editor editor = settings.edit(); - editor.putInt(Constants.PREFERENCES_KEY_SERVER_COUNT, serverCount); - // Reset set folder ID - editor.putString(Constants.PREFERENCES_KEY_MUSIC_FOLDER_ID + instance, null); - editor.putString(Constants.PREFERENCES_KEY_SERVER_URL + instance, "http://yourhost"); - editor.putString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, getResources().getString(R.string.settings_server_unused)); - editor.apply(); - - ServerSettings ss = new ServerSettings(instance); - serverSettings.put(String.valueOf(instance), ss); - ss.update(); - - return true; - } - }); - - serversCategory.setOrderingAsAdded(false); - for (int i = 1; i <= serverCount; i++) { - serversCategory.addPreference(addServer(i)); - serverSettings.put(String.valueOf(i), new ServerSettings(i)); - } - } - - SharedPreferences prefs = Util.getPreferences(context); - prefs.registerOnSharedPreferenceChangeListener(this); - - update(); - } - - private void scheduleBackup() { - try { - Class managerClass = Class.forName("android.app.backup.BackupManager"); - Constructor managerConstructor = managerClass.getConstructor(Context.class); - Object manager = managerConstructor.newInstance(context); - Method m = managerClass.getMethod("dataChanged"); - m.invoke(manager); - } catch(ClassNotFoundException e) { - Log.e(TAG, "No backup manager found"); - } catch(Throwable t) { - Log.e(TAG, "Scheduling backup failed " + t); - t.printStackTrace(); - } - } - - private void update() { - if (testingConnection) { - return; - } - - if(theme != null) { - theme.setSummary(theme.getEntry()); - } - - if(cacheSize != null) { - maxBitrateWifi.setSummary(maxBitrateWifi.getEntry()); - maxBitrateMobile.setSummary(maxBitrateMobile.getEntry()); - networkTimeout.setSummary(networkTimeout.getEntry()); - cacheLocation.setSummary(cacheLocation.getText()); - preloadCountWifi.setSummary(preloadCountWifi.getEntry()); - preloadCountMobile.setSummary(preloadCountMobile.getEntry()); - - try { - if(megabyteFromat == null) { - megabyteFromat = new DecimalFormat(getResources().getString(R.string.util_bytes_format_megabyte)); - } - - cacheSize.setSummary(megabyteFromat.format((double) Integer.parseInt(cacheSize.getText())).replace(".00", "")); - } catch(Exception e) { - Log.e(TAG, "Failed to format cache size", e); - cacheSize.setSummary(cacheSize.getText()); - } - } - - if(keepPlayedCount != null) { - keepPlayedCount.setSummary(keepPlayedCount.getEntry()); - tempLoss.setSummary(tempLoss.getEntry()); - pauseDisconnect.setSummary(pauseDisconnect.getEntry()); - songPressAction.setSummary(songPressAction.getEntry()); - - if(replayGain.isChecked()) { - replayGainType.setEnabled(true); - replayGainBump.setEnabled(true); - replayGainUntagged.setEnabled(true); - } else { - replayGainType.setEnabled(false); - replayGainBump.setEnabled(false); - replayGainUntagged.setEnabled(false); - } - replayGainType.setSummary(replayGainType.getEntry()); - } - - if(syncEnabled != null) { - syncInterval.setSummary(syncInterval.getEntry()); - - if(syncEnabled.isChecked()) { - if(!syncInterval.isEnabled()) { - syncInterval.setEnabled(true); - syncWifi.setEnabled(true); - syncNotification.setEnabled(true); - syncMostRecent.setEnabled(true); - } - } else { - if(syncInterval.isEnabled()) { - syncInterval.setEnabled(false); - syncWifi.setEnabled(false); - syncNotification.setEnabled(false); - syncMostRecent.setEnabled(false); - } - } - } - - for (ServerSettings ss : serverSettings.values()) { - ss.update(); - } - } - public void checkForRemoved() { - for (ServerSettings ss : serverSettings.values()) { - if(!ss.update()) { - serversCategory.removePreference(ss.getScreen()); - serverCount--; - } - } - } - - private PreferenceScreen addServer(final int instance) { - final PreferenceScreen screen = this.getPreferenceManager().createPreferenceScreen(context); - screen.setKey(Constants.PREFERENCES_KEY_SERVER_KEY + instance); - screen.setOrder(instance); - - screen.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - SettingsFragment newFragment = new SettingsFragment(); - - Bundle args = new Bundle(); - args.putInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, instance); - newFragment.setArguments(args); - - replaceFragment(newFragment); - return false; - } - }); - - return screen; - } - - private PreferenceScreen expandServer(final int instance) { - final PreferenceScreen screen = this.getPreferenceManager().createPreferenceScreen(context); - screen.setTitle(R.string.settings_server_unused); - screen.setKey(Constants.PREFERENCES_KEY_SERVER_KEY + instance); - - final EditTextPreference serverNamePreference = new EditTextPreference(context); - serverNamePreference.setKey(Constants.PREFERENCES_KEY_SERVER_NAME + instance); - serverNamePreference.setDefaultValue(getResources().getString(R.string.settings_server_unused)); - serverNamePreference.setTitle(R.string.settings_server_name); - serverNamePreference.setDialogTitle(R.string.settings_server_name); - - if (serverNamePreference.getText() == null) { - serverNamePreference.setText(getResources().getString(R.string.settings_server_unused)); - } - - serverNamePreference.setSummary(serverNamePreference.getText()); - - final EditTextPreference serverUrlPreference = new EditTextPreference(context); - serverUrlPreference.setKey(Constants.PREFERENCES_KEY_SERVER_URL + instance); - serverUrlPreference.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_URI); - serverUrlPreference.setDefaultValue("http://yourhost"); - serverUrlPreference.setTitle(R.string.settings_server_address); - serverUrlPreference.setDialogTitle(R.string.settings_server_address); - - if (serverUrlPreference.getText() == null) { - serverUrlPreference.setText("http://yourhost"); - } - - serverUrlPreference.setSummary(serverUrlPreference.getText()); - screen.setSummary(serverUrlPreference.getText()); - - final EditTextPreference serverLocalNetworkSSIDPreference = new EditTextPreference(context) { - @Override - protected void onAddEditTextToDialogView(View dialogView, final EditText editText) { - super.onAddEditTextToDialogView(dialogView, editText); - ViewGroup root = (ViewGroup) ((ViewGroup) dialogView).getChildAt(0); - - Button defaultButton = new Button(getContext()); - defaultButton.setText(internalSSIDDisplay); - defaultButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - editText.setText(internalSSID); - } - }); - root.addView(defaultButton); - } - }; - serverLocalNetworkSSIDPreference.setKey(Constants.PREFERENCES_KEY_SERVER_LOCAL_NETWORK_SSID + instance); - serverLocalNetworkSSIDPreference.setTitle(R.string.settings_server_local_network_ssid); - serverLocalNetworkSSIDPreference.setDialogTitle(R.string.settings_server_local_network_ssid); - - final EditTextPreference serverInternalUrlPreference = new EditTextPreference(context); - serverInternalUrlPreference.setKey(Constants.PREFERENCES_KEY_SERVER_INTERNAL_URL + instance); - serverInternalUrlPreference.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_URI); - serverInternalUrlPreference.setDefaultValue(""); - serverInternalUrlPreference.setTitle(R.string.settings_server_internal_address); - serverInternalUrlPreference.setDialogTitle(R.string.settings_server_internal_address); - serverInternalUrlPreference.setSummary(serverInternalUrlPreference.getText()); - - final EditTextPreference serverUsernamePreference = new EditTextPreference(context); - serverUsernamePreference.setKey(Constants.PREFERENCES_KEY_USERNAME + instance); - serverUsernamePreference.setTitle(R.string.settings_server_username); - serverUsernamePreference.setDialogTitle(R.string.settings_server_username); - - final EditTextPreference serverPasswordPreference = new EditTextPreference(context); - serverPasswordPreference.setKey(Constants.PREFERENCES_KEY_PASSWORD + instance); - serverPasswordPreference.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); - serverPasswordPreference.setSummary("***"); - serverPasswordPreference.setTitle(R.string.settings_server_password); - - final Preference serverOpenBrowser = new Preference(context); - serverOpenBrowser.setKey(Constants.PREFERENCES_KEY_OPEN_BROWSER); - serverOpenBrowser.setPersistent(false); - serverOpenBrowser.setTitle(R.string.settings_server_open_browser); - serverOpenBrowser.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openInBrowser(instance); - return true; - } - }); - - Preference serverRemoveServerPreference = new Preference(context); - serverRemoveServerPreference.setKey(Constants.PREFERENCES_KEY_SERVER_REMOVE + instance); - serverRemoveServerPreference.setPersistent(false); - serverRemoveServerPreference.setTitle(R.string.settings_servers_remove); - - serverRemoveServerPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Util.confirmDialog(context, R.string.common_delete, screen.getTitle().toString(), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - // Reset values to null so when we ask for them again they are new - serverNamePreference.setText(null); - serverUrlPreference.setText(null); - serverUsernamePreference.setText(null); - serverPasswordPreference.setText(null); - - // Don't use Util.getActiveServer since it is 0 if offline - int activeServer = Util.getPreferences(context).getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1); - for (int i = instance; i <= serverCount; i++) { - Util.removeInstanceName(context, i, activeServer); - } - - serverCount--; - SharedPreferences.Editor editor = settings.edit(); - editor.putInt(Constants.PREFERENCES_KEY_SERVER_COUNT, serverCount); - editor.apply(); - - removeCurrent(); - - SubsonicFragment parentFragment = context.getCurrentFragment(); - if(parentFragment instanceof SettingsFragment) { - SettingsFragment serverSelectionFragment = (SettingsFragment) parentFragment; - serverSelectionFragment.checkForRemoved(); - } - } - }); - - return true; - } - }); - - Preference serverTestConnectionPreference = new Preference(context); - serverTestConnectionPreference.setKey(Constants.PREFERENCES_KEY_TEST_CONNECTION + instance); - serverTestConnectionPreference.setPersistent(false); - serverTestConnectionPreference.setTitle(R.string.settings_test_connection_title); - serverTestConnectionPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - testConnection(instance); - return false; - } - }); - - screen.addPreference(serverNamePreference); - screen.addPreference(serverUrlPreference); - screen.addPreference(serverInternalUrlPreference); - screen.addPreference(serverLocalNetworkSSIDPreference); - screen.addPreference(serverUsernamePreference); - screen.addPreference(serverPasswordPreference); - screen.addPreference(serverTestConnectionPreference); - screen.addPreference(serverOpenBrowser); - screen.addPreference(serverRemoveServerPreference); - - return screen; - } - - private void setHideMedia(boolean hide) { - File nomediaDir = new File(FileUtil.getSubsonicDirectory(context), ".nomedia"); - File musicNoMedia = new File(FileUtil.getMusicDirectory(context), ".nomedia"); - if (hide && !nomediaDir.exists()) { - try { - if (!nomediaDir.createNewFile()) { - Log.w(TAG, "Failed to create " + nomediaDir); - } - } catch(Exception e) { - Log.w(TAG, "Failed to create " + nomediaDir, e); - } - - try { - if(!musicNoMedia.createNewFile()) { - Log.w(TAG, "Failed to create " + musicNoMedia); - } - } catch(Exception e) { - Log.w(TAG, "Failed to create " + musicNoMedia, e); - } - } else if (!hide && nomediaDir.exists()) { - if (!nomediaDir.delete()) { - Log.w(TAG, "Failed to delete " + nomediaDir); - } - if(!musicNoMedia.delete()) { - Log.w(TAG, "Failed to delete " + musicNoMedia); - } - } - Util.toast(context, R.string.settings_hide_media_toast, false); - } - - private void setMediaButtonsEnabled(boolean enabled) { - if (enabled) { - Util.registerMediaButtonEventReceiver(context); - } else { - Util.unregisterMediaButtonEventReceiver(context); - } - } - - private void setCacheLocation(String path) { - File dir = new File(path); - if (!FileUtil.verifyCanWrite(dir)) { - Util.toast(context, R.string.settings_cache_location_error, false); - - // Reset it to the default. - String defaultPath = FileUtil.getDefaultMusicDirectory(context).getPath(); - if (!defaultPath.equals(path)) { - SharedPreferences prefs = Util.getPreferences(context); - SharedPreferences.Editor editor = prefs.edit(); - editor.putString(Constants.PREFERENCES_KEY_CACHE_LOCATION, defaultPath); - editor.apply(); - - if(cacheLocation != null) { - cacheLocation.setSummary(defaultPath); - cacheLocation.setText(defaultPath); - } - } - - // Clear download queue. - DownloadService downloadService = DownloadService.getInstance(); - downloadService.clear(); - } - } - - private void testConnection(final int instance) { - LoadingTask task = new LoadingTask(context) { - private int previousInstance; - - @Override - protected Boolean doInBackground() throws Throwable { - updateProgress(R.string.settings_testing_connection); - - previousInstance = Util.getActiveServer(context); - testingConnection = true; - MusicService musicService = MusicServiceFactory.getMusicService(context); - try { - musicService.setInstance(instance); - musicService.ping(context, this); return true; - } finally { - musicService.setInstance(null); - testingConnection = false; - } - } + } + }); + syncInterval.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + Integer syncInterval = Integer.parseInt(((String) newValue)); - @Override - protected void done(Boolean licenseValid) { + Account account = new Account(Constants.SYNC_ACCOUNT_NAME, Constants.SYNC_ACCOUNT_TYPE); + ContentResolver.addPeriodicSync(account, Constants.SYNC_ACCOUNT_PLAYLIST_AUTHORITY, new Bundle(), 60L * syncInterval); + + return true; + } + }); + } + + if(serversCategory != null) { + addServerPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + serverCount++; + int instance = serverCount; + serversCategory.addPreference(addServer(serverCount)); + + SharedPreferences.Editor editor = settings.edit(); + editor.putInt(Constants.PREFERENCES_KEY_SERVER_COUNT, serverCount); + // Reset set folder ID + editor.putString(Constants.PREFERENCES_KEY_MUSIC_FOLDER_ID + instance, null); + editor.putString(Constants.PREFERENCES_KEY_SERVER_URL + instance, "http://yourhost"); + editor.putString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, getResources().getString(R.string.settings_server_unused)); + editor.apply(); + + ServerSettings ss = new ServerSettings(instance); + serverSettings.put(String.valueOf(instance), ss); + ss.update(); + + return true; + } + }); + + serversCategory.setOrderingAsAdded(false); + for (int i = 1; i <= serverCount; i++) { + serversCategory.addPreference(addServer(i)); + serverSettings.put(String.valueOf(i), new ServerSettings(i)); + } + } + + SharedPreferences prefs = Util.getPreferences(context); + prefs.registerOnSharedPreferenceChangeListener(this); + + update(); + } + + private void scheduleBackup() { + try { + Class managerClass = Class.forName("android.app.backup.BackupManager"); + Constructor managerConstructor = managerClass.getConstructor(Context.class); + Object manager = managerConstructor.newInstance(context); + Method m = managerClass.getMethod("dataChanged"); + m.invoke(manager); + } catch(ClassNotFoundException e) { + Log.e(TAG, "No backup manager found"); + } catch(Throwable t) { + Log.e(TAG, "Scheduling backup failed " + t); + t.printStackTrace(); + } + } + + private void update() { + if (testingConnection) { + return; + } + + if(theme != null) { + theme.setSummary(theme.getEntry()); + } + + if(cacheSize != null) { + maxBitrateWifi.setSummary(maxBitrateWifi.getEntry()); + maxBitrateMobile.setSummary(maxBitrateMobile.getEntry()); + networkTimeout.setSummary(networkTimeout.getEntry()); + cacheLocation.setSummary(cacheLocation.getText()); + preloadCountWifi.setSummary(preloadCountWifi.getEntry()); + preloadCountMobile.setSummary(preloadCountMobile.getEntry()); + + try { + if(megabyteFromat == null) { + megabyteFromat = new DecimalFormat(getResources().getString(R.string.util_bytes_format_megabyte)); + } + + cacheSize.setSummary(megabyteFromat.format((double) Integer.parseInt(cacheSize.getText())).replace(".00", "")); + } catch(Exception e) { + Log.e(TAG, "Failed to format cache size", e); + cacheSize.setSummary(cacheSize.getText()); + } + } + + if(keepPlayedCount != null) { + keepPlayedCount.setSummary(keepPlayedCount.getEntry()); + tempLoss.setSummary(tempLoss.getEntry()); + pauseDisconnect.setSummary(pauseDisconnect.getEntry()); + songPressAction.setSummary(songPressAction.getEntry()); + + if(replayGain.isChecked()) { + replayGainType.setEnabled(true); + replayGainBump.setEnabled(true); + replayGainUntagged.setEnabled(true); + } else { + replayGainType.setEnabled(false); + replayGainBump.setEnabled(false); + replayGainUntagged.setEnabled(false); + } + replayGainType.setSummary(replayGainType.getEntry()); + } + + if(syncEnabled != null) { + syncInterval.setSummary(syncInterval.getEntry()); + + if(syncEnabled.isChecked()) { + if(!syncInterval.isEnabled()) { + syncInterval.setEnabled(true); + syncWifi.setEnabled(true); + syncNotification.setEnabled(true); + syncMostRecent.setEnabled(true); + } + } else { + if(syncInterval.isEnabled()) { + syncInterval.setEnabled(false); + syncWifi.setEnabled(false); + syncNotification.setEnabled(false); + syncMostRecent.setEnabled(false); + } + } + } + + for (ServerSettings ss : serverSettings.values()) { + ss.update(); + } + } + public void checkForRemoved() { + for (ServerSettings ss : serverSettings.values()) { + if(!ss.update()) { + serversCategory.removePreference(ss.getScreen()); + serverCount--; + } + } + } + + private PreferenceScreen addServer(final int instance) { + final PreferenceScreen screen = this.getPreferenceManager().createPreferenceScreen(context); + screen.setKey(Constants.PREFERENCES_KEY_SERVER_KEY + instance); + screen.setOrder(instance); + + screen.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + SettingsFragment newFragment = new SettingsFragment(); + + Bundle args = new Bundle(); + args.putInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, instance); + newFragment.setArguments(args); + + replaceFragment(newFragment); + return false; + } + }); + + return screen; + } + + private PreferenceScreen expandServer(final int instance) { + final PreferenceScreen screen = this.getPreferenceManager().createPreferenceScreen(context); + screen.setTitle(R.string.settings_server_unused); + screen.setKey(Constants.PREFERENCES_KEY_SERVER_KEY + instance); + + final EditTextPreference serverNamePreference = new EditTextPreference(context); + serverNamePreference.setKey(Constants.PREFERENCES_KEY_SERVER_NAME + instance); + serverNamePreference.setDefaultValue(getResources().getString(R.string.settings_server_unused)); + serverNamePreference.setTitle(R.string.settings_server_name); + serverNamePreference.setDialogTitle(R.string.settings_server_name); + + if (serverNamePreference.getText() == null) { + serverNamePreference.setText(getResources().getString(R.string.settings_server_unused)); + } + + serverNamePreference.setSummary(serverNamePreference.getText()); + + final EditTextPreference serverUrlPreference = new EditTextPreference(context); + serverUrlPreference.setKey(Constants.PREFERENCES_KEY_SERVER_URL + instance); + serverUrlPreference.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_URI); + serverUrlPreference.setDefaultValue("http://yourhost"); + serverUrlPreference.setTitle(R.string.settings_server_address); + serverUrlPreference.setDialogTitle(R.string.settings_server_address); + + if (serverUrlPreference.getText() == null) { + serverUrlPreference.setText("http://yourhost"); + } + + serverUrlPreference.setSummary(serverUrlPreference.getText()); + screen.setSummary(serverUrlPreference.getText()); + + final EditTextPreference serverLocalNetworkSSIDPreference = new EditTextPreference(context) { + @Override + protected void onAddEditTextToDialogView(View dialogView, final EditText editText) { + super.onAddEditTextToDialogView(dialogView, editText); + ViewGroup root = (ViewGroup) ((ViewGroup) dialogView).getChildAt(0); + + Button defaultButton = new Button(getContext()); + defaultButton.setText(internalSSIDDisplay); + defaultButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + editText.setText(internalSSID); + } + }); + root.addView(defaultButton); + } + }; + serverLocalNetworkSSIDPreference.setKey(Constants.PREFERENCES_KEY_SERVER_LOCAL_NETWORK_SSID + instance); + serverLocalNetworkSSIDPreference.setTitle(R.string.settings_server_local_network_ssid); + serverLocalNetworkSSIDPreference.setDialogTitle(R.string.settings_server_local_network_ssid); + + final EditTextPreference serverInternalUrlPreference = new EditTextPreference(context); + serverInternalUrlPreference.setKey(Constants.PREFERENCES_KEY_SERVER_INTERNAL_URL + instance); + serverInternalUrlPreference.getEditText().setInputType(InputType.TYPE_TEXT_VARIATION_URI); + serverInternalUrlPreference.setDefaultValue(""); + serverInternalUrlPreference.setTitle(R.string.settings_server_internal_address); + serverInternalUrlPreference.setDialogTitle(R.string.settings_server_internal_address); + serverInternalUrlPreference.setSummary(serverInternalUrlPreference.getText()); + + final EditTextPreference serverUsernamePreference = new EditTextPreference(context); + serverUsernamePreference.setKey(Constants.PREFERENCES_KEY_USERNAME + instance); + serverUsernamePreference.setTitle(R.string.settings_server_username); + serverUsernamePreference.setDialogTitle(R.string.settings_server_username); + + final EditTextPreference serverPasswordPreference = new EditTextPreference(context); + serverPasswordPreference.setKey(Constants.PREFERENCES_KEY_PASSWORD + instance); + serverPasswordPreference.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + serverPasswordPreference.setSummary("***"); + serverPasswordPreference.setTitle(R.string.settings_server_password); + + final Preference serverOpenBrowser = new Preference(context); + serverOpenBrowser.setKey(Constants.PREFERENCES_KEY_OPEN_BROWSER); + serverOpenBrowser.setPersistent(false); + serverOpenBrowser.setTitle(R.string.settings_server_open_browser); + serverOpenBrowser.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + openInBrowser(instance); + return true; + } + }); + + Preference serverRemoveServerPreference = new Preference(context); + serverRemoveServerPreference.setKey(Constants.PREFERENCES_KEY_SERVER_REMOVE + instance); + serverRemoveServerPreference.setPersistent(false); + serverRemoveServerPreference.setTitle(R.string.settings_servers_remove); + + serverRemoveServerPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + Util.confirmDialog(context, R.string.common_delete, screen.getTitle().toString(), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Reset values to null so when we ask for them again they are new + serverNamePreference.setText(null); + serverUrlPreference.setText(null); + serverUsernamePreference.setText(null); + serverPasswordPreference.setText(null); + + // Don't use Util.getActiveServer since it is 0 if offline + int activeServer = Util.getPreferences(context).getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1); + for (int i = instance; i <= serverCount; i++) { + Util.removeInstanceName(context, i, activeServer); + } + + serverCount--; + SharedPreferences.Editor editor = settings.edit(); + editor.putInt(Constants.PREFERENCES_KEY_SERVER_COUNT, serverCount); + editor.apply(); + + removeCurrent(); + + SubsonicFragment parentFragment = context.getCurrentFragment(); + if(parentFragment instanceof SettingsFragment) { + SettingsFragment serverSelectionFragment = (SettingsFragment) parentFragment; + serverSelectionFragment.checkForRemoved(); + } + } + }); + + return true; + } + }); + + Preference serverTestConnectionPreference = new Preference(context); + serverTestConnectionPreference.setKey(Constants.PREFERENCES_KEY_TEST_CONNECTION + instance); + serverTestConnectionPreference.setPersistent(false); + serverTestConnectionPreference.setTitle(R.string.settings_test_connection_title); + serverTestConnectionPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + testConnection(instance); + return false; + } + }); + + screen.addPreference(serverNamePreference); + screen.addPreference(serverUrlPreference); + screen.addPreference(serverInternalUrlPreference); + screen.addPreference(serverLocalNetworkSSIDPreference); + screen.addPreference(serverUsernamePreference); + screen.addPreference(serverPasswordPreference); + screen.addPreference(serverTestConnectionPreference); + screen.addPreference(serverOpenBrowser); + screen.addPreference(serverRemoveServerPreference); + + return screen; + } + + private void setHideMedia(boolean hide) { + File nomediaDir = new File(FileUtil.getSubsonicDirectory(context), ".nomedia"); + File musicNoMedia = new File(FileUtil.getMusicDirectory(context), ".nomedia"); + if (hide && !nomediaDir.exists()) { + try { + if (!nomediaDir.createNewFile()) { + Log.w(TAG, "Failed to create " + nomediaDir); + } + } catch(Exception e) { + Log.w(TAG, "Failed to create " + nomediaDir, e); + } + + try { + if(!musicNoMedia.createNewFile()) { + Log.w(TAG, "Failed to create " + musicNoMedia); + } + } catch(Exception e) { + Log.w(TAG, "Failed to create " + musicNoMedia, e); + } + } else if (!hide && nomediaDir.exists()) { + if (!nomediaDir.delete()) { + Log.w(TAG, "Failed to delete " + nomediaDir); + } + if(!musicNoMedia.delete()) { + Log.w(TAG, "Failed to delete " + musicNoMedia); + } + } + Util.toast(context, R.string.settings_hide_media_toast, false); + } + + private void setMediaButtonsEnabled(boolean enabled) { + if (enabled) { + Util.registerMediaButtonEventReceiver(context); + } else { + Util.unregisterMediaButtonEventReceiver(context); + } + } + + private void setCacheLocation(String path) { + File dir = new File(path); + if (!FileUtil.verifyCanWrite(dir)) { + Util.toast(context, R.string.settings_cache_location_error, false); + + // Reset it to the default. + String defaultPath = FileUtil.getDefaultMusicDirectory(context).getPath(); + if (!defaultPath.equals(path)) { + SharedPreferences prefs = Util.getPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(Constants.PREFERENCES_KEY_CACHE_LOCATION, defaultPath); + editor.apply(); + + if(cacheLocation != null) { + cacheLocation.setSummary(defaultPath); + cacheLocation.setText(defaultPath); + } + } + + // Clear download queue. + DownloadService downloadService = DownloadService.getInstance(); + downloadService.clear(); + } + } + + private void testConnection(final int instance) { + LoadingTask task = new LoadingTask(context) { + private int previousInstance; + + @Override + protected Boolean doInBackground() throws Throwable { + updateProgress(R.string.settings_testing_connection); + + previousInstance = Util.getActiveServer(context); + testingConnection = true; + MusicService musicService = MusicServiceFactory.getMusicService(context); + try { + musicService.setInstance(instance); + musicService.ping(context, this); + return true; + } finally { + musicService.setInstance(null); + testingConnection = false; + } + } + + @Override + protected void done(Boolean licenseValid) { Util.toast(context, R.string.settings_testing_ok); - } + } - @Override - public void cancel() { - super.cancel(); - Util.setActiveServer(context, previousInstance); - } + @Override + public void cancel() { + super.cancel(); + Util.setActiveServer(context, previousInstance); + } - @Override - protected void error(Throwable error) { - Log.w(TAG, error.toString(), error); - new ErrorDialog(context, getResources().getString(R.string.settings_connection_failure) + - " " + getErrorMessage(error), false); - } - }; - task.execute(); - } + @Override + protected void error(Throwable error) { + Log.w(TAG, error.toString(), error); + new ErrorDialog(context, getResources().getString(R.string.settings_connection_failure) + + " " + getErrorMessage(error), false); + } + }; + task.execute(); + } - private void openInBrowser(final int instance) { - SharedPreferences prefs = Util.getPreferences(context); - String url = prefs.getString(Constants.PREFERENCES_KEY_SERVER_URL + instance, null); - if(url == null) { - new ErrorDialog(context, R.string.settings_invalid_url, false); - return; - } - Uri uriServer = Uri.parse(url); + private void openInBrowser(final int instance) { + SharedPreferences prefs = Util.getPreferences(context); + String url = prefs.getString(Constants.PREFERENCES_KEY_SERVER_URL + instance, null); + if(url == null) { + new ErrorDialog(context, R.string.settings_invalid_url, false); + return; + } + Uri uriServer = Uri.parse(url); - Intent browserIntent = new Intent(Intent.ACTION_VIEW, uriServer); - startActivity(browserIntent); - } + Intent browserIntent = new Intent(Intent.ACTION_VIEW, uriServer); + startActivity(browserIntent); + } - private class ServerSettings { - private int instance; - private EditTextPreference serverName; - private EditTextPreference serverUrl; - private EditTextPreference serverLocalNetworkSSID; - private EditTextPreference serverInternalUrl; - private EditTextPreference username; - private PreferenceScreen screen; + private class ServerSettings { + private int instance; + private EditTextPreference serverName; + private EditTextPreference serverUrl; + private EditTextPreference serverLocalNetworkSSID; + private EditTextPreference serverInternalUrl; + private EditTextPreference username; + private PreferenceScreen screen; - private ServerSettings(int instance) { - this.instance = instance; - screen = (PreferenceScreen) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_SERVER_KEY + instance); - serverName = (EditTextPreference) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_SERVER_NAME + instance); - serverUrl = (EditTextPreference) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_SERVER_URL + instance); - serverLocalNetworkSSID = (EditTextPreference) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_SERVER_LOCAL_NETWORK_SSID + instance); - serverInternalUrl = (EditTextPreference) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_SERVER_INTERNAL_URL + instance); - username = (EditTextPreference) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_USERNAME + instance); + private ServerSettings(int instance) { + this.instance = instance; + screen = (PreferenceScreen) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_SERVER_KEY + instance); + serverName = (EditTextPreference) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_SERVER_NAME + instance); + serverUrl = (EditTextPreference) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_SERVER_URL + instance); + serverLocalNetworkSSID = (EditTextPreference) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_SERVER_LOCAL_NETWORK_SSID + instance); + serverInternalUrl = (EditTextPreference) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_SERVER_INTERNAL_URL + instance); + username = (EditTextPreference) SettingsFragment.this.findPreference(Constants.PREFERENCES_KEY_USERNAME + instance); - if(serverName != null) { - serverUrl.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - try { - String url = (String) value; - new URL(url); - if (url.contains(" ") || url.contains("@") || url.contains("_")) { - throw new Exception(); - } - } catch (Exception x) { - new ErrorDialog(context, R.string.settings_invalid_url, false); - return false; - } - return true; - } - }); - serverInternalUrl.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - try { - String url = (String) value; - // Allow blank internal IP address - if ("".equals(url) || url == null) { - return true; - } + if(serverName != null) { + serverUrl.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object value) { + try { + String url = (String) value; + new URL(url); + if (url.contains(" ") || url.contains("@") || url.contains("_")) { + throw new Exception(); + } + } catch (Exception x) { + new ErrorDialog(context, R.string.settings_invalid_url, false); + return false; + } + return true; + } + }); + serverInternalUrl.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object value) { + try { + String url = (String) value; + // Allow blank internal IP address + if ("".equals(url) || url == null) { + return true; + } - new URL(url); - if (url.contains(" ") || url.contains("@") || url.contains("_")) { - throw new Exception(); - } - } catch (Exception x) { - new ErrorDialog(context, R.string.settings_invalid_url, false); - return false; - } - return true; - } - }); + new URL(url); + if (url.contains(" ") || url.contains("@") || url.contains("_")) { + throw new Exception(); + } + } catch (Exception x) { + new ErrorDialog(context, R.string.settings_invalid_url, false); + return false; + } + return true; + } + }); - username.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - String username = (String) value; - if (username == null || !username.equals(username.trim())) { - new ErrorDialog(context, R.string.settings_invalid_username, false); - return false; - } - return true; - } - }); - } - } + username.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object value) { + String username = (String) value; + if (username == null || !username.equals(username.trim())) { + new ErrorDialog(context, R.string.settings_invalid_username, false); + return false; + } + return true; + } + }); + } + } - public PreferenceScreen getScreen() { - return screen; - } + public PreferenceScreen getScreen() { + return screen; + } - public boolean update() { - SharedPreferences prefs = Util.getPreferences(context); + public boolean update() { + SharedPreferences prefs = Util.getPreferences(context); - if(prefs.contains(Constants.PREFERENCES_KEY_SERVER_NAME + instance)) { - if (serverName != null) { - serverName.setSummary(serverName.getText()); - serverUrl.setSummary(serverUrl.getText()); - serverLocalNetworkSSID.setSummary(serverLocalNetworkSSID.getText()); - serverInternalUrl.setSummary(serverInternalUrl.getText()); - username.setSummary(username.getText()); + if(prefs.contains(Constants.PREFERENCES_KEY_SERVER_NAME + instance)) { + if (serverName != null) { + serverName.setSummary(serverName.getText()); + serverUrl.setSummary(serverUrl.getText()); + serverLocalNetworkSSID.setSummary(serverLocalNetworkSSID.getText()); + serverInternalUrl.setSummary(serverInternalUrl.getText()); + username.setSummary(username.getText()); - setTitle(serverName.getText()); - } + setTitle(serverName.getText()); + } - String title = prefs.getString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, null); - String summary = prefs.getString(Constants.PREFERENCES_KEY_SERVER_URL + instance, null); + String title = prefs.getString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, null); + String summary = prefs.getString(Constants.PREFERENCES_KEY_SERVER_URL + instance, null); - if (title != null) { - screen.setTitle(title); - } else { - screen.setTitle(R.string.settings_server_unused); - } - if (summary != null) { - screen.setSummary(summary); - } + if (title != null) { + screen.setTitle(title); + } else { + screen.setTitle(R.string.settings_server_unused); + } + if (summary != null) { + screen.setSummary(summary); + } - return true; - } else { - return false; - } - } - } + return true; + } else { + return false; + } + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/fragments/SubsonicFragment.java b/app/src/main/java/net/nullsum/audinaut/fragments/SubsonicFragment.java index 5694adf..742ce71 100644 --- a/app/src/main/java/net/nullsum/audinaut/fragments/SubsonicFragment.java +++ b/app/src/main/java/net/nullsum/audinaut/fragments/SubsonicFragment.java @@ -100,572 +100,572 @@ import java.util.Random; import static net.nullsum.audinaut.domain.MusicDirectory.Entry; public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener { - private static final String TAG = SubsonicFragment.class.getSimpleName(); - private static int TAG_INC = 10; - private int tag; + private static final String TAG = SubsonicFragment.class.getSimpleName(); + private static int TAG_INC = 10; + private int tag; - protected SubsonicActivity context; - protected CharSequence title = null; - protected CharSequence subtitle = null; - protected View rootView; - protected boolean primaryFragment = false; - protected boolean secondaryFragment = false; - protected boolean isOnlyVisible = true; - protected boolean alwaysFullscreen = false; - protected boolean alwaysStartFullscreen = false; - protected boolean invalidated = false; - protected static Random random = new Random(); - protected GestureDetector gestureScanner; - protected boolean artist = false; - protected boolean artistOverride = false; - protected SwipeRefreshLayout refreshLayout; - protected boolean firstRun; - protected MenuItem searchItem; - protected SearchView searchView; + protected SubsonicActivity context; + protected CharSequence title = null; + protected CharSequence subtitle = null; + protected View rootView; + protected boolean primaryFragment = false; + protected boolean secondaryFragment = false; + protected boolean isOnlyVisible = true; + protected boolean alwaysFullscreen = false; + protected boolean alwaysStartFullscreen = false; + protected boolean invalidated = false; + protected static Random random = new Random(); + protected GestureDetector gestureScanner; + protected boolean artist = false; + protected boolean artistOverride = false; + protected SwipeRefreshLayout refreshLayout; + protected boolean firstRun; + protected MenuItem searchItem; + protected SearchView searchView; - public SubsonicFragment() { - super(); - tag = TAG_INC++; - } + public SubsonicFragment() { + super(); + tag = TAG_INC++; + } - @Override - public void onCreate(Bundle bundle) { - super.onCreate(bundle); + @Override + public void onCreate(Bundle bundle) { + super.onCreate(bundle); - if(bundle != null) { - String name = bundle.getString(Constants.FRAGMENT_NAME); - if(name != null) { - title = name; - } - } - firstRun = true; - } + if(bundle != null) { + String name = bundle.getString(Constants.FRAGMENT_NAME); + if(name != null) { + title = name; + } + } + firstRun = true; + } - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - if(title != null) { - outState.putString(Constants.FRAGMENT_NAME, title.toString()); - } - } + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + if(title != null) { + outState.putString(Constants.FRAGMENT_NAME, title.toString()); + } + } - @Override - public void onResume() { - super.onResume(); - if(firstRun) { - firstRun = false; - } else { - UpdateView.triggerUpdate(); - } - } + @Override + public void onResume() { + super.onResume(); + if(firstRun) { + firstRun = false; + } else { + UpdateView.triggerUpdate(); + } + } - @Override - public void onDestroy() { - super.onDestroy(); - } + @Override + public void onDestroy() { + super.onDestroy(); + } - @Override - public void onAttach(Activity activity) { - super.onAttach(activity); - context = (SubsonicActivity)activity; - } + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + context = (SubsonicActivity)activity; + } - public void setContext(SubsonicActivity context) { - this.context = context; - } + public void setContext(SubsonicActivity context) { + this.context = context; + } - protected void onFinishSetupOptionsMenu(final Menu menu) { - searchItem = menu.findItem(R.id.menu_global_search); - if(searchItem != null) { - searchView = (SearchView) MenuItemCompat.getActionView(searchItem); - SearchManager searchManager = (SearchManager) context.getSystemService(Context.SEARCH_SERVICE); - SearchableInfo searchableInfo = searchManager.getSearchableInfo(context.getComponentName()); - if(searchableInfo == null) { - Log.w(TAG, "Failed to get SearchableInfo"); - } else { - searchView.setSearchableInfo(searchableInfo); - } + protected void onFinishSetupOptionsMenu(final Menu menu) { + searchItem = menu.findItem(R.id.menu_global_search); + if(searchItem != null) { + searchView = (SearchView) MenuItemCompat.getActionView(searchItem); + SearchManager searchManager = (SearchManager) context.getSystemService(Context.SEARCH_SERVICE); + SearchableInfo searchableInfo = searchManager.getSearchableInfo(context.getComponentName()); + if(searchableInfo == null) { + Log.w(TAG, "Failed to get SearchableInfo"); + } else { + searchView.setSearchableInfo(searchableInfo); + } - String currentQuery = getCurrentQuery(); - if(currentQuery != null) { - searchView.setOnSearchClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - searchView.setQuery(getCurrentQuery(), false); - } - }); - } - } - } + String currentQuery = getCurrentQuery(); + if(currentQuery != null) { + searchView.setOnSearchClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + searchView.setQuery(getCurrentQuery(), false); + } + }); + } + } + } - @Override - public boolean onOptionsItemSelected(MenuItem item) { - switch (item.getItemId()) { - case R.id.menu_global_shuffle: - onShuffleRequested(); - return true; - case R.id.menu_refresh: - refresh(); - return true; - case R.id.menu_play_now: - playNow(false, false); - return true; - case R.id.menu_play_last: - playNow(false, true); - return true; - case R.id.menu_play_next: - playNow(false, true, true); - return true; - case R.id.menu_shuffle: - playNow(true, false); - return true; - case R.id.menu_download: - downloadBackground(false); - clearSelected(); - return true; - case R.id.menu_cache: - downloadBackground(true); - clearSelected(); - return true; - case R.id.menu_delete: - delete(); - clearSelected(); - return true; - case R.id.menu_add_playlist: - List songs = getSelectedEntries(); - addToPlaylist(songs); - clearSelected(); - return true; - } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.menu_global_shuffle: + onShuffleRequested(); + return true; + case R.id.menu_refresh: + refresh(); + return true; + case R.id.menu_play_now: + playNow(false, false); + return true; + case R.id.menu_play_last: + playNow(false, true); + return true; + case R.id.menu_play_next: + playNow(false, true, true); + return true; + case R.id.menu_shuffle: + playNow(true, false); + return true; + case R.id.menu_download: + downloadBackground(false); + clearSelected(); + return true; + case R.id.menu_cache: + downloadBackground(true); + clearSelected(); + return true; + case R.id.menu_delete: + delete(); + clearSelected(); + return true; + case R.id.menu_add_playlist: + List songs = getSelectedEntries(); + addToPlaylist(songs); + clearSelected(); + return true; + } - return false; - } + return false; + } - public void onCreateContextMenuSupport(Menu menu, MenuInflater menuInflater, UpdateView updateView, Object selected) { - if(selected instanceof Entry) { - Entry entry = (Entry) selected; - if (entry.isDirectory()) { - if(Util.isOffline(context)) { - menuInflater.inflate(R.menu.select_album_context_offline, menu); - } - else { - menuInflater.inflate(R.menu.select_album_context, menu); - } - } else { - if(Util.isOffline(context)) { - menuInflater.inflate(R.menu.select_song_context_offline, menu); - } - else { - menuInflater.inflate(R.menu.select_song_context, menu); + public void onCreateContextMenuSupport(Menu menu, MenuInflater menuInflater, UpdateView updateView, Object selected) { + if(selected instanceof Entry) { + Entry entry = (Entry) selected; + if (entry.isDirectory()) { + if(Util.isOffline(context)) { + menuInflater.inflate(R.menu.select_album_context_offline, menu); + } + else { + menuInflater.inflate(R.menu.select_album_context, menu); + } + } else { + if(Util.isOffline(context)) { + menuInflater.inflate(R.menu.select_song_context_offline, menu); + } + else { + menuInflater.inflate(R.menu.select_song_context, menu); - String songPressAction = Util.getSongPressAction(context); - if(!"next".equals(songPressAction) && !"last".equals(songPressAction)) { - menu.setGroupVisible(R.id.hide_play_now, false); - } - } - } + String songPressAction = Util.getSongPressAction(context); + if(!"next".equals(songPressAction) && !"last".equals(songPressAction)) { + menu.setGroupVisible(R.id.hide_play_now, false); + } + } + } - if(!isShowArtistEnabled() || (!Util.isTagBrowsing(context) && entry.getParent() == null) || (Util.isTagBrowsing(context) && entry.getArtistId() == null)) { - menu.setGroupVisible(R.id.hide_show_artist, false); - } - } else if(selected instanceof Artist) { - Artist artist = (Artist) selected; - if(Util.isOffline(context)) { - menuInflater.inflate(R.menu.select_artist_context_offline, menu); - } else { - menuInflater.inflate(R.menu.select_artist_context, menu); - } - } + if(!isShowArtistEnabled() || (!Util.isTagBrowsing(context) && entry.getParent() == null) || (Util.isTagBrowsing(context) && entry.getArtistId() == null)) { + menu.setGroupVisible(R.id.hide_show_artist, false); + } + } else if(selected instanceof Artist) { + Artist artist = (Artist) selected; + if(Util.isOffline(context)) { + menuInflater.inflate(R.menu.select_artist_context_offline, menu); + } else { + menuInflater.inflate(R.menu.select_artist_context, menu); + } + } - MenuUtil.hideMenuItems(context, menu, updateView); - } + MenuUtil.hideMenuItems(context, menu, updateView); + } - protected void recreateContextMenu(Menu menu) { - List menuItems = new ArrayList(); - for(int i = 0; i < menu.size(); i++) { - MenuItem item = menu.getItem(i); - if(item.isVisible()) { - menuItems.add(item); - } - } - menu.clear(); - for(int i = 0; i < menuItems.size(); i++) { - MenuItem item = menuItems.get(i); - menu.add(tag, item.getItemId(), Menu.NONE, item.getTitle()); - } - } + protected void recreateContextMenu(Menu menu) { + List menuItems = new ArrayList(); + for(int i = 0; i < menu.size(); i++) { + MenuItem item = menu.getItem(i); + if(item.isVisible()) { + menuItems.add(item); + } + } + menu.clear(); + for(int i = 0; i < menuItems.size(); i++) { + MenuItem item = menuItems.get(i); + menu.add(tag, item.getItemId(), Menu.NONE, item.getTitle()); + } + } - // For reverting specific removals: https://github.com/daneren2005/Subsonic/commit/fbd1a68042dfc3601eaa0a9e37b3957bbdd51420 - public boolean onContextItemSelected(MenuItem menuItem, Object selectedItem) { - Artist artist = selectedItem instanceof Artist ? (Artist) selectedItem : null; - Entry entry = selectedItem instanceof Entry ? (Entry) selectedItem : null; - if(selectedItem instanceof DownloadFile) { - entry = ((DownloadFile) selectedItem).getSong(); - } - List songs = new ArrayList(1); - songs.add(entry); + // For reverting specific removals: https://github.com/daneren2005/Subsonic/commit/fbd1a68042dfc3601eaa0a9e37b3957bbdd51420 + public boolean onContextItemSelected(MenuItem menuItem, Object selectedItem) { + Artist artist = selectedItem instanceof Artist ? (Artist) selectedItem : null; + Entry entry = selectedItem instanceof Entry ? (Entry) selectedItem : null; + if(selectedItem instanceof DownloadFile) { + entry = ((DownloadFile) selectedItem).getSong(); + } + List songs = new ArrayList(1); + songs.add(entry); - switch (menuItem.getItemId()) { - case R.id.artist_menu_play_now: - downloadRecursively(artist.getId(), false, false, true, false, false); - break; - case R.id.artist_menu_play_shuffled: - downloadRecursively(artist.getId(), false, false, true, true, false); - break; - case R.id.artist_menu_play_next: - downloadRecursively(artist.getId(), false, true, false, false, false, true); - break; - case R.id.artist_menu_play_last: - downloadRecursively(artist.getId(), false, true, false, false, false); - break; - case R.id.artist_menu_download: - downloadRecursively(artist.getId(), false, true, false, false, true); - break; - case R.id.artist_menu_pin: - downloadRecursively(artist.getId(), true, true, false, false, true); - break; - case R.id.artist_menu_delete: - deleteRecursively(artist); - break; - case R.id.album_menu_play_now: - artistOverride = true; - downloadRecursively(entry.getId(), false, false, true, false, false); - break; - case R.id.album_menu_play_shuffled: - artistOverride = true; - downloadRecursively(entry.getId(), false, false, true, true, false); - break; - case R.id.album_menu_play_next: - artistOverride = true; - downloadRecursively(entry.getId(), false, true, false, false, false, true); - break; - case R.id.album_menu_play_last: - artistOverride = true; - downloadRecursively(entry.getId(), false, true, false, false, false); - break; - case R.id.album_menu_download: - artistOverride = true; - downloadRecursively(entry.getId(), false, true, false, false, true); - break; - case R.id.album_menu_pin: - artistOverride = true; - downloadRecursively(entry.getId(), true, true, false, false, true); - break; - case R.id.album_menu_delete: - deleteRecursively(entry); - break; - case R.id.album_menu_info: - displaySongInfo(entry); - break; - case R.id.album_menu_show_artist: - showAlbumArtist((Entry) selectedItem); - break; - case R.id.song_menu_play_now: - playNow(songs); - break; - case R.id.song_menu_play_next: - getDownloadService().download(songs, false, false, true, false); - break; - case R.id.song_menu_play_last: - getDownloadService().download(songs, false, false, false, false); - break; - case R.id.song_menu_download: - getDownloadService().downloadBackground(songs, false); - break; - case R.id.song_menu_pin: - getDownloadService().downloadBackground(songs, true); - break; - case R.id.song_menu_delete: - deleteSongs(songs); - break; - case R.id.song_menu_add_playlist: - addToPlaylist(songs); - break; - case R.id.song_menu_info: - displaySongInfo(entry); - break; - case R.id.song_menu_show_album: - showAlbum((Entry) selectedItem); - break; - case R.id.song_menu_show_artist: - showArtist((Entry) selectedItem); - break; - default: - return false; - } + switch (menuItem.getItemId()) { + case R.id.artist_menu_play_now: + downloadRecursively(artist.getId(), false, false, true, false, false); + break; + case R.id.artist_menu_play_shuffled: + downloadRecursively(artist.getId(), false, false, true, true, false); + break; + case R.id.artist_menu_play_next: + downloadRecursively(artist.getId(), false, true, false, false, false, true); + break; + case R.id.artist_menu_play_last: + downloadRecursively(artist.getId(), false, true, false, false, false); + break; + case R.id.artist_menu_download: + downloadRecursively(artist.getId(), false, true, false, false, true); + break; + case R.id.artist_menu_pin: + downloadRecursively(artist.getId(), true, true, false, false, true); + break; + case R.id.artist_menu_delete: + deleteRecursively(artist); + break; + case R.id.album_menu_play_now: + artistOverride = true; + downloadRecursively(entry.getId(), false, false, true, false, false); + break; + case R.id.album_menu_play_shuffled: + artistOverride = true; + downloadRecursively(entry.getId(), false, false, true, true, false); + break; + case R.id.album_menu_play_next: + artistOverride = true; + downloadRecursively(entry.getId(), false, true, false, false, false, true); + break; + case R.id.album_menu_play_last: + artistOverride = true; + downloadRecursively(entry.getId(), false, true, false, false, false); + break; + case R.id.album_menu_download: + artistOverride = true; + downloadRecursively(entry.getId(), false, true, false, false, true); + break; + case R.id.album_menu_pin: + artistOverride = true; + downloadRecursively(entry.getId(), true, true, false, false, true); + break; + case R.id.album_menu_delete: + deleteRecursively(entry); + break; + case R.id.album_menu_info: + displaySongInfo(entry); + break; + case R.id.album_menu_show_artist: + showAlbumArtist((Entry) selectedItem); + break; + case R.id.song_menu_play_now: + playNow(songs); + break; + case R.id.song_menu_play_next: + getDownloadService().download(songs, false, false, true, false); + break; + case R.id.song_menu_play_last: + getDownloadService().download(songs, false, false, false, false); + break; + case R.id.song_menu_download: + getDownloadService().downloadBackground(songs, false); + break; + case R.id.song_menu_pin: + getDownloadService().downloadBackground(songs, true); + break; + case R.id.song_menu_delete: + deleteSongs(songs); + break; + case R.id.song_menu_add_playlist: + addToPlaylist(songs); + break; + case R.id.song_menu_info: + displaySongInfo(entry); + break; + case R.id.song_menu_show_album: + showAlbum((Entry) selectedItem); + break; + case R.id.song_menu_show_artist: + showArtist((Entry) selectedItem); + break; + default: + return false; + } - return true; - } + return true; + } - public void replaceFragment(SubsonicFragment fragment) { - replaceFragment(fragment, true); - } - public void replaceFragment(SubsonicFragment fragment, boolean replaceCurrent) { - context.replaceFragment(fragment, fragment.getSupportTag(), secondaryFragment && replaceCurrent); - } - public void replaceExistingFragment(SubsonicFragment fragment) { - context.replaceExistingFragment(fragment, fragment.getSupportTag()); - } - public void removeCurrent() { - context.removeCurrent(); - } + public void replaceFragment(SubsonicFragment fragment) { + replaceFragment(fragment, true); + } + public void replaceFragment(SubsonicFragment fragment, boolean replaceCurrent) { + context.replaceFragment(fragment, fragment.getSupportTag(), secondaryFragment && replaceCurrent); + } + public void replaceExistingFragment(SubsonicFragment fragment) { + context.replaceExistingFragment(fragment, fragment.getSupportTag()); + } + public void removeCurrent() { + context.removeCurrent(); + } - public int getRootId() { - return rootView.getId(); - } + public int getRootId() { + return rootView.getId(); + } - public void setSupportTag(int tag) { this.tag = tag; } - public void setSupportTag(String tag) { this.tag = Integer.parseInt(tag); } - public int getSupportTag() { - return tag; - } + public void setSupportTag(int tag) { this.tag = tag; } + public void setSupportTag(String tag) { this.tag = Integer.parseInt(tag); } + public int getSupportTag() { + return tag; + } - public void setPrimaryFragment(boolean primary) { - primaryFragment = primary; - if(primary) { - if(context != null && title != null) { - context.setTitle(title); - context.setSubtitle(subtitle); - } - if(invalidated) { - invalidated = false; - refresh(false); - } - } - } - public void setPrimaryFragment(boolean primary, boolean secondary) { - setPrimaryFragment(primary); - secondaryFragment = secondary; - } - public void setSecondaryFragment(boolean secondary) { - secondaryFragment = secondary; - } - public void setIsOnlyVisible(boolean isOnlyVisible) { - this.isOnlyVisible = isOnlyVisible; - } - public boolean isAlwaysFullscreen() { - return alwaysFullscreen; - } - public boolean isAlwaysStartFullscreen() { - return alwaysStartFullscreen; - } + public void setPrimaryFragment(boolean primary) { + primaryFragment = primary; + if(primary) { + if(context != null && title != null) { + context.setTitle(title); + context.setSubtitle(subtitle); + } + if(invalidated) { + invalidated = false; + refresh(false); + } + } + } + public void setPrimaryFragment(boolean primary, boolean secondary) { + setPrimaryFragment(primary); + secondaryFragment = secondary; + } + public void setSecondaryFragment(boolean secondary) { + secondaryFragment = secondary; + } + public void setIsOnlyVisible(boolean isOnlyVisible) { + this.isOnlyVisible = isOnlyVisible; + } + public boolean isAlwaysFullscreen() { + return alwaysFullscreen; + } + public boolean isAlwaysStartFullscreen() { + return alwaysStartFullscreen; + } - public void invalidate() { - if(primaryFragment) { - refresh(true); - } else { - invalidated = true; - } - } + public void invalidate() { + if(primaryFragment) { + refresh(true); + } else { + invalidated = true; + } + } - public DownloadService getDownloadService() { - return context != null ? context.getDownloadService() : null; - } + public DownloadService getDownloadService() { + return context != null ? context.getDownloadService() : null; + } - protected void refresh() { - refresh(true); - } - protected void refresh(boolean refresh) { + protected void refresh() { + refresh(true); + } + protected void refresh(boolean refresh) { - } + } - @Override - public void onRefresh() { - refreshLayout.setRefreshing(false); - refresh(); - } + @Override + public void onRefresh() { + refreshLayout.setRefreshing(false); + refresh(); + } - public void setProgressVisible(boolean visible) { - View view = rootView.findViewById(R.id.tab_progress); - if (view != null) { - view.setVisibility(visible ? View.VISIBLE : View.GONE); + public void setProgressVisible(boolean visible) { + View view = rootView.findViewById(R.id.tab_progress); + if (view != null) { + view.setVisibility(visible ? View.VISIBLE : View.GONE); - if(visible) { - View progress = rootView.findViewById(R.id.tab_progress_spinner); - progress.setVisibility(View.VISIBLE); - } - } - } + if(visible) { + View progress = rootView.findViewById(R.id.tab_progress_spinner); + progress.setVisibility(View.VISIBLE); + } + } + } - public void updateProgress(String message) { - TextView view = (TextView) rootView.findViewById(R.id.tab_progress_message); - if (view != null) { - view.setText(message); - } - } + public void updateProgress(String message) { + TextView view = (TextView) rootView.findViewById(R.id.tab_progress_message); + if (view != null) { + view.setText(message); + } + } - public void setEmpty(boolean empty) { - View view = rootView.findViewById(R.id.tab_progress); - if(empty) { - view.setVisibility(View.VISIBLE); + public void setEmpty(boolean empty) { + View view = rootView.findViewById(R.id.tab_progress); + if(empty) { + view.setVisibility(View.VISIBLE); - View progress = view.findViewById(R.id.tab_progress_spinner); - progress.setVisibility(View.GONE); + View progress = view.findViewById(R.id.tab_progress_spinner); + progress.setVisibility(View.GONE); - TextView text = (TextView) view.findViewById(R.id.tab_progress_message); - text.setText(R.string.common_empty); - } else { - view.setVisibility(View.GONE); - } - } + TextView text = (TextView) view.findViewById(R.id.tab_progress_message); + text.setText(R.string.common_empty); + } else { + view.setVisibility(View.GONE); + } + } - protected synchronized ImageLoader getImageLoader() { - return context.getImageLoader(); - } - public synchronized static ImageLoader getStaticImageLoader(Context context) { - return SubsonicActivity.getStaticImageLoader(context); - } + protected synchronized ImageLoader getImageLoader() { + return context.getImageLoader(); + } + public synchronized static ImageLoader getStaticImageLoader(Context context) { + return SubsonicActivity.getStaticImageLoader(context); + } - public void setTitle(CharSequence title) { - this.title = title; - context.setTitle(title); - } - public void setTitle(int title) { - this.title = context.getResources().getString(title); - context.setTitle(this.title); - } - public void setSubtitle(CharSequence title) { - this.subtitle = title; - context.setSubtitle(title); - } - public CharSequence getTitle() { - return this.title; - } + public void setTitle(CharSequence title) { + this.title = title; + context.setTitle(title); + } + public void setTitle(int title) { + this.title = context.getResources().getString(title); + context.setTitle(this.title); + } + public void setSubtitle(CharSequence title) { + this.subtitle = title; + context.setSubtitle(title); + } + public CharSequence getTitle() { + return this.title; + } - protected void setupScrollList(final AbsListView listView) { - if(!context.isTouchscreen()) { - refreshLayout.setEnabled(false); - } else { - listView.setOnScrollListener(new AbsListView.OnScrollListener() { - @Override - public void onScrollStateChanged(AbsListView view, int scrollState) { - } + protected void setupScrollList(final AbsListView listView) { + if(!context.isTouchscreen()) { + refreshLayout.setEnabled(false); + } else { + listView.setOnScrollListener(new AbsListView.OnScrollListener() { + @Override + public void onScrollStateChanged(AbsListView view, int scrollState) { + } - @Override - public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { - int topRowVerticalPosition = (listView.getChildCount() == 0) ? 0 : listView.getChildAt(0).getTop(); - refreshLayout.setEnabled(topRowVerticalPosition >= 0 && listView.getFirstVisiblePosition() == 0); - } - }); - } - } - protected void setupScrollList(final RecyclerView recyclerView) { - if(!context.isTouchscreen()) { - refreshLayout.setEnabled(false); - } else { - recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { - @Override - public void onScrollStateChanged(RecyclerView recyclerView, int newState) { - super.onScrollStateChanged(recyclerView, newState); - } + @Override + public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { + int topRowVerticalPosition = (listView.getChildCount() == 0) ? 0 : listView.getChildAt(0).getTop(); + refreshLayout.setEnabled(topRowVerticalPosition >= 0 && listView.getFirstVisiblePosition() == 0); + } + }); + } + } + protected void setupScrollList(final RecyclerView recyclerView) { + if(!context.isTouchscreen()) { + refreshLayout.setEnabled(false); + } else { + recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() { + @Override + public void onScrollStateChanged(RecyclerView recyclerView, int newState) { + super.onScrollStateChanged(recyclerView, newState); + } - @Override - public void onScrolled(RecyclerView recyclerView, int dx, int dy) { - refreshLayout.setEnabled(!recyclerView.canScrollVertically(-1)); - } - }); - } - } + @Override + public void onScrolled(RecyclerView recyclerView, int dx, int dy) { + refreshLayout.setEnabled(!recyclerView.canScrollVertically(-1)); + } + }); + } + } - public void setupLayoutManager(RecyclerView recyclerView, boolean largeAlbums) { - recyclerView.setLayoutManager(getLayoutManager(recyclerView, largeAlbums)); - } - public RecyclerView.LayoutManager getLayoutManager(RecyclerView recyclerView, boolean largeCells) { - if(largeCells) { - return getGridLayoutManager(recyclerView); - } else { - return getLinearLayoutManager(); - } - } - public GridLayoutManager getGridLayoutManager(RecyclerView recyclerView) { - final int columns = getRecyclerColumnCount(); - GridLayoutManager gridLayoutManager = new GridLayoutManager(context, columns); + public void setupLayoutManager(RecyclerView recyclerView, boolean largeAlbums) { + recyclerView.setLayoutManager(getLayoutManager(recyclerView, largeAlbums)); + } + public RecyclerView.LayoutManager getLayoutManager(RecyclerView recyclerView, boolean largeCells) { + if(largeCells) { + return getGridLayoutManager(recyclerView); + } else { + return getLinearLayoutManager(); + } + } + public GridLayoutManager getGridLayoutManager(RecyclerView recyclerView) { + final int columns = getRecyclerColumnCount(); + GridLayoutManager gridLayoutManager = new GridLayoutManager(context, columns); - GridLayoutManager.SpanSizeLookup spanSizeLookup = getSpanSizeLookup(gridLayoutManager); - if(spanSizeLookup != null) { - gridLayoutManager.setSpanSizeLookup(spanSizeLookup); - } - RecyclerView.ItemDecoration itemDecoration = getItemDecoration(); - if(itemDecoration != null) { - recyclerView.addItemDecoration(itemDecoration); - } - return gridLayoutManager; - } - public LinearLayoutManager getLinearLayoutManager() { - LinearLayoutManager layoutManager = new LinearLayoutManager(context); - layoutManager.setOrientation(LinearLayoutManager.VERTICAL); - return layoutManager; - } - public GridLayoutManager.SpanSizeLookup getSpanSizeLookup(final GridLayoutManager gridLayoutManager) { - return new GridLayoutManager.SpanSizeLookup() { - @Override - public int getSpanSize(int position) { - SectionAdapter adapter = getCurrentAdapter(); - if(adapter != null) { - int viewType = adapter.getItemViewType(position); - if (viewType == SectionAdapter.VIEW_TYPE_HEADER) { - return gridLayoutManager.getSpanCount(); - } else { - return 1; - } - } else { - return 1; - } - } - }; - } - public RecyclerView.ItemDecoration getItemDecoration() { - return new GridSpacingDecoration(); - } - public int getRecyclerColumnCount() { - if(isOnlyVisible) { - return context.getResources().getInteger(R.integer.Grid_FullScreen_Columns); - } else { - return context.getResources().getInteger(R.integer.Grid_Columns); - } - } + GridLayoutManager.SpanSizeLookup spanSizeLookup = getSpanSizeLookup(gridLayoutManager); + if(spanSizeLookup != null) { + gridLayoutManager.setSpanSizeLookup(spanSizeLookup); + } + RecyclerView.ItemDecoration itemDecoration = getItemDecoration(); + if(itemDecoration != null) { + recyclerView.addItemDecoration(itemDecoration); + } + return gridLayoutManager; + } + public LinearLayoutManager getLinearLayoutManager() { + LinearLayoutManager layoutManager = new LinearLayoutManager(context); + layoutManager.setOrientation(LinearLayoutManager.VERTICAL); + return layoutManager; + } + public GridLayoutManager.SpanSizeLookup getSpanSizeLookup(final GridLayoutManager gridLayoutManager) { + return new GridLayoutManager.SpanSizeLookup() { + @Override + public int getSpanSize(int position) { + SectionAdapter adapter = getCurrentAdapter(); + if(adapter != null) { + int viewType = adapter.getItemViewType(position); + if (viewType == SectionAdapter.VIEW_TYPE_HEADER) { + return gridLayoutManager.getSpanCount(); + } else { + return 1; + } + } else { + return 1; + } + } + }; + } + public RecyclerView.ItemDecoration getItemDecoration() { + return new GridSpacingDecoration(); + } + public int getRecyclerColumnCount() { + if(isOnlyVisible) { + return context.getResources().getInteger(R.integer.Grid_FullScreen_Columns); + } else { + return context.getResources().getInteger(R.integer.Grid_Columns); + } + } - protected void warnIfStorageUnavailable() { - if (!Util.isExternalStoragePresent()) { - Util.toast(context, R.string.select_album_no_sdcard); - } + protected void warnIfStorageUnavailable() { + if (!Util.isExternalStoragePresent()) { + Util.toast(context, R.string.select_album_no_sdcard); + } - try { - StatFs stat = new StatFs(FileUtil.getMusicDirectory(context).getPath()); - long bytesAvailableFs = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); - if (bytesAvailableFs < 50000000L) { - Util.toast(context, context.getResources().getString(R.string.select_album_no_room, Util.formatBytes(bytesAvailableFs))); - } - } catch(Exception e) { - Log.w(TAG, "Error while checking storage space for music directory", e); - } - } + try { + StatFs stat = new StatFs(FileUtil.getMusicDirectory(context).getPath()); + long bytesAvailableFs = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); + if (bytesAvailableFs < 50000000L) { + Util.toast(context, context.getResources().getString(R.string.select_album_no_room, Util.formatBytes(bytesAvailableFs))); + } + } catch(Exception e) { + Log.w(TAG, "Error while checking storage space for music directory", e); + } + } - protected void onShuffleRequested() { - if(Util.isOffline(context)) { - DownloadService downloadService = getDownloadService(); - if(downloadService == null) { - return; - } - downloadService.clear(); - downloadService.setShufflePlayEnabled(true); - context.openNowPlaying(); - return; - } + protected void onShuffleRequested() { + if(Util.isOffline(context)) { + DownloadService downloadService = getDownloadService(); + if(downloadService == null) { + return; + } + downloadService.clear(); + downloadService.setShufflePlayEnabled(true); + context.openNowPlaying(); + return; + } - View dialogView = context.getLayoutInflater().inflate(R.layout.shuffle_dialog, null); - final EditText startYearBox = (EditText)dialogView.findViewById(R.id.start_year); - final EditText endYearBox = (EditText)dialogView.findViewById(R.id.end_year); - final EditText genreBox = (EditText)dialogView.findViewById(R.id.genre); - final Button genreCombo = (Button)dialogView.findViewById(R.id.genre_combo); + View dialogView = context.getLayoutInflater().inflate(R.layout.shuffle_dialog, null); + final EditText startYearBox = (EditText)dialogView.findViewById(R.id.start_year); + final EditText endYearBox = (EditText)dialogView.findViewById(R.id.end_year); + final EditText genreBox = (EditText)dialogView.findViewById(R.id.genre); + final Button genreCombo = (Button)dialogView.findViewById(R.id.genre_combo); - final SharedPreferences prefs = Util.getPreferences(context); - final String oldStartYear = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, ""); - final String oldEndYear = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, ""); - final String oldGenre = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, ""); + final SharedPreferences prefs = Util.getPreferences(context); + final String oldStartYear = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, ""); + final String oldEndYear = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, ""); + final String oldGenre = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, ""); - boolean _useCombo = false; + boolean _useCombo = false; genreBox.setVisibility(View.GONE); genreCombo.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { @@ -716,442 +716,442 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR } }); _useCombo = true; - final boolean useCombo = _useCombo; + final boolean useCombo = _useCombo; - startYearBox.setText(oldStartYear); - endYearBox.setText(oldEndYear); - genreBox.setText(oldGenre); - genreCombo.setText(oldGenre); + startYearBox.setText(oldStartYear); + endYearBox.setText(oldEndYear); + genreBox.setText(oldGenre); + genreCombo.setText(oldGenre); - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.shuffle_title) - .setView(dialogView) - .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - String genre; - if (useCombo) { - genre = genreCombo.getText().toString(); - } else { - genre = genreBox.getText().toString(); - } - String startYear = startYearBox.getText().toString(); - String endYear = endYearBox.getText().toString(); + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.shuffle_title) + .setView(dialogView) + .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + String genre; + if (useCombo) { + genre = genreCombo.getText().toString(); + } else { + genre = genreBox.getText().toString(); + } + String startYear = startYearBox.getText().toString(); + String endYear = endYearBox.getText().toString(); - SharedPreferences.Editor editor = prefs.edit(); - editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, startYear); - editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, endYear); - editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, genre); - editor.apply(); + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, startYear); + editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, endYear); + editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, genre); + editor.apply(); - DownloadService downloadService = getDownloadService(); - if (downloadService == null) { - return; - } + DownloadService downloadService = getDownloadService(); + if (downloadService == null) { + return; + } - downloadService.clear(); - downloadService.setShufflePlayEnabled(true); - context.openNowPlaying(); - } - }) - .setNegativeButton(R.string.common_cancel, null); - AlertDialog dialog = builder.create(); - dialog.show(); - } + downloadService.clear(); + downloadService.setShufflePlayEnabled(true); + context.openNowPlaying(); + } + }) + .setNegativeButton(R.string.common_cancel, null); + AlertDialog dialog = builder.create(); + dialog.show(); + } - protected void downloadRecursively(final String id, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background) { - downloadRecursively(id, "", true, save, append, autoplay, shuffle, background); - } - protected void downloadRecursively(final String id, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background, final boolean playNext) { - downloadRecursively(id, "", true, save, append, autoplay, shuffle, background, playNext); - } - protected void downloadPlaylist(final String id, final String name, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background) { - downloadRecursively(id, name, false, save, append, autoplay, shuffle, background); - } + protected void downloadRecursively(final String id, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background) { + downloadRecursively(id, "", true, save, append, autoplay, shuffle, background); + } + protected void downloadRecursively(final String id, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background, final boolean playNext) { + downloadRecursively(id, "", true, save, append, autoplay, shuffle, background, playNext); + } + protected void downloadPlaylist(final String id, final String name, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background) { + downloadRecursively(id, name, false, save, append, autoplay, shuffle, background); + } - protected void downloadRecursively(final String id, final String name, final boolean isDirectory, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background) { - downloadRecursively(id, name, isDirectory, save, append, autoplay, shuffle, background, false); - } + protected void downloadRecursively(final String id, final String name, final boolean isDirectory, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background) { + downloadRecursively(id, name, isDirectory, save, append, autoplay, shuffle, background, false); + } - protected void downloadRecursively(final String id, final String name, final boolean isDirectory, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background, final boolean playNext) { - new RecursiveLoader(context) { - @Override - protected Boolean doInBackground() throws Throwable { - musicService = MusicServiceFactory.getMusicService(context); - MusicDirectory root; - if(isDirectory && id != null) { + protected void downloadRecursively(final String id, final String name, final boolean isDirectory, final boolean save, final boolean append, final boolean autoplay, final boolean shuffle, final boolean background, final boolean playNext) { + new RecursiveLoader(context) { + @Override + protected Boolean doInBackground() throws Throwable { + musicService = MusicServiceFactory.getMusicService(context); + MusicDirectory root; + if(isDirectory && id != null) { root = getMusicDirectory(id, name, false, musicService, this); - } else { - root = musicService.getPlaylist(true, id, name, context, this); - } + } else { + root = musicService.getPlaylist(true, id, name, context, this); + } - boolean shuffleByAlbum = Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_SHUFFLE_BY_ALBUM, true); - if(shuffle && shuffleByAlbum) { - Collections.shuffle(root.getChildren()); - } + boolean shuffleByAlbum = Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_SHUFFLE_BY_ALBUM, true); + if(shuffle && shuffleByAlbum) { + Collections.shuffle(root.getChildren()); + } - songs = new LinkedList(); - getSongsRecursively(root, songs); + songs = new LinkedList(); + getSongsRecursively(root, songs); - if(shuffle && !shuffleByAlbum) { - Collections.shuffle(songs); - } + if(shuffle && !shuffleByAlbum) { + Collections.shuffle(songs); + } - DownloadService downloadService = getDownloadService(); - boolean transition = false; - if (!songs.isEmpty() && downloadService != null) { - // Conditions for a standard play now operation - if(!append && !save && autoplay && !playNext && !shuffle && !background) { - playNowOverride = true; - return false; - } + DownloadService downloadService = getDownloadService(); + boolean transition = false; + if (!songs.isEmpty() && downloadService != null) { + // Conditions for a standard play now operation + if(!append && !save && autoplay && !playNext && !shuffle && !background) { + playNowOverride = true; + return false; + } - if (!append && !background) { - downloadService.clear(); - } - if(!background) { - downloadService.download(songs, save, autoplay, playNext, false); - if(!append) { - transition = true; - } - } - else { - downloadService.downloadBackground(songs, save); - } - } - artistOverride = false; + if (!append && !background) { + downloadService.clear(); + } + if(!background) { + downloadService.download(songs, save, autoplay, playNext, false); + if(!append) { + transition = true; + } + } + else { + downloadService.downloadBackground(songs, save); + } + } + artistOverride = false; - return transition; - } - }.execute(); - } + return transition; + } + }.execute(); + } - protected void downloadRecursively(final List albums, final boolean shuffle, final boolean append, final boolean playNext) { - new RecursiveLoader(context) { - @Override - protected Boolean doInBackground() throws Throwable { - musicService = MusicServiceFactory.getMusicService(context); + protected void downloadRecursively(final List albums, final boolean shuffle, final boolean append, final boolean playNext) { + new RecursiveLoader(context) { + @Override + protected Boolean doInBackground() throws Throwable { + musicService = MusicServiceFactory.getMusicService(context); - if(shuffle) { - Collections.shuffle(albums); - } + if(shuffle) { + Collections.shuffle(albums); + } - songs = new LinkedList(); - MusicDirectory root = new MusicDirectory(); - root.addChildren(albums); - getSongsRecursively(root, songs); + songs = new LinkedList(); + MusicDirectory root = new MusicDirectory(); + root.addChildren(albums); + getSongsRecursively(root, songs); - DownloadService downloadService = getDownloadService(); - boolean transition = false; - if (!songs.isEmpty() && downloadService != null) { - // Conditions for a standard play now operation - if(!append && !shuffle) { - playNowOverride = true; - return false; - } + DownloadService downloadService = getDownloadService(); + boolean transition = false; + if (!songs.isEmpty() && downloadService != null) { + // Conditions for a standard play now operation + if(!append && !shuffle) { + playNowOverride = true; + return false; + } - if (!append) { - downloadService.clear(); - } + if (!append) { + downloadService.clear(); + } - downloadService.download(songs, false, true, playNext, false); - if(!append) { - transition = true; - } - } - artistOverride = false; + downloadService.download(songs, false, true, playNext, false); + if(!append) { + transition = true; + } + } + artistOverride = false; - return transition; - } - }.execute(); - } + return transition; + } + }.execute(); + } - protected MusicDirectory getMusicDirectory(String id, String name, boolean refresh, MusicService service, ProgressListener listener) throws Exception { - return getMusicDirectory(id, name, refresh, false, service, listener); - } - protected MusicDirectory getMusicDirectory(String id, String name, boolean refresh, boolean forceArtist, MusicService service, ProgressListener listener) throws Exception { - if(Util.isTagBrowsing(context) && !Util.isOffline(context)) { - if(artist && !artistOverride || forceArtist) { - return service.getArtist(id, name, refresh, context, listener); - } else { - return service.getAlbum(id, name, refresh, context, listener); - } - } else { - return service.getMusicDirectory(id, name, refresh, context, listener); - } - } + protected MusicDirectory getMusicDirectory(String id, String name, boolean refresh, MusicService service, ProgressListener listener) throws Exception { + return getMusicDirectory(id, name, refresh, false, service, listener); + } + protected MusicDirectory getMusicDirectory(String id, String name, boolean refresh, boolean forceArtist, MusicService service, ProgressListener listener) throws Exception { + if(Util.isTagBrowsing(context) && !Util.isOffline(context)) { + if(artist && !artistOverride || forceArtist) { + return service.getArtist(id, name, refresh, context, listener); + } else { + return service.getAlbum(id, name, refresh, context, listener); + } + } else { + return service.getMusicDirectory(id, name, refresh, context, listener); + } + } - protected void addToPlaylist(final List songs) { - Iterator it = songs.iterator(); - while(it.hasNext()) { - Entry entry = it.next(); - if(entry.isDirectory()) { - it.remove(); - } - } + protected void addToPlaylist(final List songs) { + Iterator it = songs.iterator(); + while(it.hasNext()) { + Entry entry = it.next(); + if(entry.isDirectory()) { + it.remove(); + } + } - if(songs.isEmpty()) { - Util.toast(context, "No songs selected"); - return; - } + if(songs.isEmpty()) { + Util.toast(context, "No songs selected"); + return; + } - new LoadingTask>(context, true) { - @Override - protected List doInBackground() throws Throwable { - MusicService musicService = MusicServiceFactory.getMusicService(context); - List playlists = new ArrayList(); - playlists.addAll(musicService.getPlaylists(false, context, this)); + new LoadingTask>(context, true) { + @Override + protected List doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + List playlists = new ArrayList(); + playlists.addAll(musicService.getPlaylists(false, context, this)); - // Iterate through and remove all non owned public playlists - Iterator it = playlists.iterator(); - while(it.hasNext()) { - Playlist playlist = it.next(); - if(playlist.getPublic() == true && playlist.getId().indexOf(".m3u") == -1 && !UserUtil.getCurrentUsername(context).equals(playlist.getOwner())) { - it.remove(); - } - } + // Iterate through and remove all non owned public playlists + Iterator it = playlists.iterator(); + while(it.hasNext()) { + Playlist playlist = it.next(); + if(playlist.getPublic() == true && playlist.getId().indexOf(".m3u") == -1 && !UserUtil.getCurrentUsername(context).equals(playlist.getOwner())) { + it.remove(); + } + } - return playlists; - } + return playlists; + } - @Override - protected void done(final List playlists) { - // Create adapter to show playlists - Playlist createNew = new Playlist("-1", context.getResources().getString(R.string.playlist_create_new)); - playlists.add(0, createNew); - ArrayAdapter playlistAdapter = new ArrayAdapter(context, R.layout.basic_count_item, playlists) { - @Override - public View getView(int position, View convertView, ViewGroup parent) { - Playlist playlist = getItem(position); + @Override + protected void done(final List playlists) { + // Create adapter to show playlists + Playlist createNew = new Playlist("-1", context.getResources().getString(R.string.playlist_create_new)); + playlists.add(0, createNew); + ArrayAdapter playlistAdapter = new ArrayAdapter(context, R.layout.basic_count_item, playlists) { + @Override + public View getView(int position, View convertView, ViewGroup parent) { + Playlist playlist = getItem(position); - // Create new if not getting a convert view to use - PlaylistSongView view; - if(convertView instanceof PlaylistSongView) { - view = (PlaylistSongView) convertView; - } else { - view = new PlaylistSongView(context); - } + // Create new if not getting a convert view to use + PlaylistSongView view; + if(convertView instanceof PlaylistSongView) { + view = (PlaylistSongView) convertView; + } else { + view = new PlaylistSongView(context); + } - view.setObject(playlist, songs); + view.setObject(playlist, songs); - return view; - } - }; + return view; + } + }; - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.playlist_add_to) - .setAdapter(playlistAdapter, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - if (which > 0) { - addToPlaylist(playlists.get(which), songs); - } else { - createNewPlaylist(songs, false); - } - } - }); - AlertDialog dialog = builder.create(); - dialog.show(); - } + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.playlist_add_to) + .setAdapter(playlistAdapter, new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + if (which > 0) { + addToPlaylist(playlists.get(which), songs); + } else { + createNewPlaylist(songs, false); + } + } + }); + AlertDialog dialog = builder.create(); + dialog.show(); + } - @Override - protected void error(Throwable error) { - String msg; - if (error instanceof OfflineException) { - msg = getErrorMessage(error); - } else { - msg = context.getResources().getString(R.string.playlist_error) + " " + getErrorMessage(error); - } + @Override + protected void error(Throwable error) { + String msg; + if (error instanceof OfflineException) { + msg = getErrorMessage(error); + } else { + msg = context.getResources().getString(R.string.playlist_error) + " " + getErrorMessage(error); + } - Util.toast(context, msg, false); - } - }.execute(); - } + Util.toast(context, msg, false); + } + }.execute(); + } - private void addToPlaylist(final Playlist playlist, final List songs) { - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - MusicService musicService = MusicServiceFactory.getMusicService(context); - musicService.addToPlaylist(playlist.getId(), songs, context, null); - return null; - } + private void addToPlaylist(final Playlist playlist, final List songs) { + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + musicService.addToPlaylist(playlist.getId(), songs, context, null); + return null; + } - @Override - protected void done(Void result) { - Util.toast(context, context.getResources().getString(R.string.updated_playlist, songs.size(), playlist.getName())); - } + @Override + protected void done(Void result) { + Util.toast(context, context.getResources().getString(R.string.updated_playlist, songs.size(), playlist.getName())); + } - @Override - protected void error(Throwable error) { - String msg; - if (error instanceof OfflineException) { - msg = getErrorMessage(error); - } else { - msg = context.getResources().getString(R.string.updated_playlist_error, playlist.getName()) + " " + getErrorMessage(error); - } + @Override + protected void error(Throwable error) { + String msg; + if (error instanceof OfflineException) { + msg = getErrorMessage(error); + } else { + msg = context.getResources().getString(R.string.updated_playlist_error, playlist.getName()) + " " + getErrorMessage(error); + } - Util.toast(context, msg, false); - } - }.execute(); - } + Util.toast(context, msg, false); + } + }.execute(); + } - protected void createNewPlaylist(final List songs, final boolean getSuggestion) { - View layout = context.getLayoutInflater().inflate(R.layout.save_playlist, null); - final EditText playlistNameView = (EditText) layout.findViewById(R.id.save_playlist_name); - final CheckBox overwriteCheckBox = (CheckBox) layout.findViewById(R.id.save_playlist_overwrite); - if(getSuggestion) { - String playlistName = (getDownloadService() != null) ? getDownloadService().getSuggestedPlaylistName() : null; - if (playlistName != null) { - playlistNameView.setText(playlistName); - try { - if(Integer.parseInt(getDownloadService().getSuggestedPlaylistId()) != -1) { - overwriteCheckBox.setChecked(true); - overwriteCheckBox.setVisibility(View.VISIBLE); - } - } catch(Exception e) { - Log.i(TAG, "Playlist id isn't a integer, probably MusicCabinet"); - } - } else { - DateFormat dateFormat = DateFormat.getDateInstance(); - playlistNameView.setText(dateFormat.format(new Date())); - } - } else { - DateFormat dateFormat = DateFormat.getDateInstance(); playlistNameView.setText(dateFormat.format(new Date())); - } + protected void createNewPlaylist(final List songs, final boolean getSuggestion) { + View layout = context.getLayoutInflater().inflate(R.layout.save_playlist, null); + final EditText playlistNameView = (EditText) layout.findViewById(R.id.save_playlist_name); + final CheckBox overwriteCheckBox = (CheckBox) layout.findViewById(R.id.save_playlist_overwrite); + if(getSuggestion) { + String playlistName = (getDownloadService() != null) ? getDownloadService().getSuggestedPlaylistName() : null; + if (playlistName != null) { + playlistNameView.setText(playlistName); + try { + if(Integer.parseInt(getDownloadService().getSuggestedPlaylistId()) != -1) { + overwriteCheckBox.setChecked(true); + overwriteCheckBox.setVisibility(View.VISIBLE); + } + } catch(Exception e) { + Log.i(TAG, "Playlist id isn't a integer, probably MusicCabinet"); + } + } else { + DateFormat dateFormat = DateFormat.getDateInstance(); + playlistNameView.setText(dateFormat.format(new Date())); + } + } else { + DateFormat dateFormat = DateFormat.getDateInstance(); playlistNameView.setText(dateFormat.format(new Date())); + } - AlertDialog.Builder builder = new AlertDialog.Builder(context); - builder.setTitle(R.string.download_playlist_title) - .setMessage(R.string.download_playlist_name) - .setView(layout) - .setPositiveButton(R.string.common_save, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - String playlistName = String.valueOf(playlistNameView.getText()); - if(overwriteCheckBox.isChecked()) { - overwritePlaylist(songs, playlistName, getDownloadService().getSuggestedPlaylistId()); - } else { - createNewPlaylist(songs, playlistName); + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.download_playlist_title) + .setMessage(R.string.download_playlist_name) + .setView(layout) + .setPositiveButton(R.string.common_save, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + String playlistName = String.valueOf(playlistNameView.getText()); + if(overwriteCheckBox.isChecked()) { + overwritePlaylist(songs, playlistName, getDownloadService().getSuggestedPlaylistId()); + } else { + createNewPlaylist(songs, playlistName); - if(getSuggestion) { - DownloadService downloadService = getDownloadService(); - if(downloadService != null) { - downloadService.setSuggestedPlaylistName(playlistName, null); - } - } - } - } - }) - .setNegativeButton(R.string.common_cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { - dialog.cancel(); - } - }) - .setCancelable(true); + if(getSuggestion) { + DownloadService downloadService = getDownloadService(); + if(downloadService != null) { + downloadService.setSuggestedPlaylistName(playlistName, null); + } + } + } + } + }) + .setNegativeButton(R.string.common_cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int id) { + dialog.cancel(); + } + }) + .setCancelable(true); - AlertDialog dialog = builder.create(); - dialog.show(); - } - private void createNewPlaylist(final List songs, final String name) { - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - MusicService musicService = MusicServiceFactory.getMusicService(context); - musicService.createPlaylist(null, name, songs, context, null); - return null; - } + AlertDialog dialog = builder.create(); + dialog.show(); + } + private void createNewPlaylist(final List songs, final String name) { + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + musicService.createPlaylist(null, name, songs, context, null); + return null; + } - @Override - protected void done(Void result) { - Util.toast(context, R.string.download_playlist_done); - } + @Override + protected void done(Void result) { + Util.toast(context, R.string.download_playlist_done); + } - @Override - protected void error(Throwable error) { - String msg = context.getResources().getString(R.string.download_playlist_error) + " " + getErrorMessage(error); - Util.toast(context, msg); - } - }.execute(); - } - private void overwritePlaylist(final List songs, final String name, final String id) { - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - MusicService musicService = MusicServiceFactory.getMusicService(context); - MusicDirectory playlist = musicService.getPlaylist(true, id, name, context, null); - List toDelete = playlist.getChildren(); - musicService.overwritePlaylist(id, name, toDelete.size(), songs, context, null); - return null; - } + @Override + protected void error(Throwable error) { + String msg = context.getResources().getString(R.string.download_playlist_error) + " " + getErrorMessage(error); + Util.toast(context, msg); + } + }.execute(); + } + private void overwritePlaylist(final List songs, final String name, final String id) { + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + MusicService musicService = MusicServiceFactory.getMusicService(context); + MusicDirectory playlist = musicService.getPlaylist(true, id, name, context, null); + List toDelete = playlist.getChildren(); + musicService.overwritePlaylist(id, name, toDelete.size(), songs, context, null); + return null; + } - @Override - protected void done(Void result) { - Util.toast(context, R.string.download_playlist_done); - } + @Override + protected void done(Void result) { + Util.toast(context, R.string.download_playlist_done); + } - @Override - protected void error(Throwable error) { - String msg; - if (error instanceof OfflineException) { - msg = getErrorMessage(error); - } else { - msg = context.getResources().getString(R.string.download_playlist_error) + " " + getErrorMessage(error); - } + @Override + protected void error(Throwable error) { + String msg; + if (error instanceof OfflineException) { + msg = getErrorMessage(error); + } else { + msg = context.getResources().getString(R.string.download_playlist_error) + " " + getErrorMessage(error); + } - Util.toast(context, msg, false); - } - }.execute(); - } + Util.toast(context, msg, false); + } + }.execute(); + } - public void displaySongInfo(final Entry song) { - Integer duration = null; - Integer bitrate = null; - String format = null; - long size = 0; - if(!song.isDirectory()) { - try { - DownloadFile downloadFile = new DownloadFile(context, song, false); - File file = downloadFile.getCompleteFile(); - if(file.exists()) { - MediaMetadataRetriever metadata = new MediaMetadataRetriever(); - metadata.setDataSource(file.getAbsolutePath()); + public void displaySongInfo(final Entry song) { + Integer duration = null; + Integer bitrate = null; + String format = null; + long size = 0; + if(!song.isDirectory()) { + try { + DownloadFile downloadFile = new DownloadFile(context, song, false); + File file = downloadFile.getCompleteFile(); + if(file.exists()) { + MediaMetadataRetriever metadata = new MediaMetadataRetriever(); + metadata.setDataSource(file.getAbsolutePath()); - String tmp = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); - duration = Integer.parseInt((tmp != null) ? tmp : "0") / 1000; - format = FileUtil.getExtension(file.getName()); - size = file.length(); + String tmp = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); + duration = Integer.parseInt((tmp != null) ? tmp : "0") / 1000; + format = FileUtil.getExtension(file.getName()); + size = file.length(); - // If no duration try to read bitrate tag - if(duration == null) { - tmp = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE); - bitrate = Integer.parseInt((tmp != null) ? tmp : "0") / 1000; - } else { - // Otherwise do a calculation for it - // Divide by 1000 so in kbps - bitrate = (int) (size / duration) / 1000 * 8; - } + // If no duration try to read bitrate tag + if(duration == null) { + tmp = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_BITRATE); + bitrate = Integer.parseInt((tmp != null) ? tmp : "0") / 1000; + } else { + // Otherwise do a calculation for it + // Divide by 1000 so in kbps + bitrate = (int) (size / duration) / 1000 * 8; + } - if(Util.isOffline(context)) { - song.setGenre(metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE)); - String year = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR); - song.setYear(Integer.parseInt((year != null) ? year : "0")); - } - } - } catch(Exception e) { - Log.i(TAG, "Device doesn't properly support MediaMetadataRetreiver"); - } - } - if(duration == null) { - duration = song.getDuration(); - } + if(Util.isOffline(context)) { + song.setGenre(metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_GENRE)); + String year = metadata.extractMetadata(MediaMetadataRetriever.METADATA_KEY_YEAR); + song.setYear(Integer.parseInt((year != null) ? year : "0")); + } + } + } catch(Exception e) { + Log.i(TAG, "Device doesn't properly support MediaMetadataRetreiver"); + } + } + if(duration == null) { + duration = song.getDuration(); + } - List headers = new ArrayList<>(); - List details = new ArrayList<>(); + List headers = new ArrayList<>(); + List details = new ArrayList<>(); - if(!song.isDirectory()) { - headers.add(R.string.details_title); - details.add(song.getTitle()); - } + if(!song.isDirectory()) { + headers.add(R.string.details_title); + details.add(song.getTitle()); + } if(song.getArtist() != null && !"".equals(song.getArtist())) { headers.add(R.string.details_artist); @@ -1160,473 +1160,473 @@ public class SubsonicFragment extends Fragment implements SwipeRefreshLayout.OnR if(song.getAlbum() != null && !"".equals(song.getAlbum())) { headers.add(R.string.details_album); details.add(song.getAlbum()); - } - if(song.getTrack() != null && song.getTrack() != 0) { - headers.add(R.string.details_track); - details.add(Integer.toString(song.getTrack())); - } - if(song.getGenre() != null && !"".equals(song.getGenre())) { - headers.add(R.string.details_genre); - details.add(song.getGenre()); - } - if(song.getYear() != null && song.getYear() != 0) { - headers.add(R.string.details_year); - details.add(Integer.toString(song.getYear())); - } - if(!Util.isOffline(context) && song.getSuffix() != null) { - headers.add(R.string.details_server_format); - details.add(song.getSuffix()); + } + if(song.getTrack() != null && song.getTrack() != 0) { + headers.add(R.string.details_track); + details.add(Integer.toString(song.getTrack())); + } + if(song.getGenre() != null && !"".equals(song.getGenre())) { + headers.add(R.string.details_genre); + details.add(song.getGenre()); + } + if(song.getYear() != null && song.getYear() != 0) { + headers.add(R.string.details_year); + details.add(Integer.toString(song.getYear())); + } + if(!Util.isOffline(context) && song.getSuffix() != null) { + headers.add(R.string.details_server_format); + details.add(song.getSuffix()); - if(song.getBitRate() != null && song.getBitRate() != 0) { - headers.add(R.string.details_server_bitrate); - details.add(song.getBitRate() + " kbps"); - } - } - if(format != null && !"".equals(format)) { - headers.add(R.string.details_cached_format); - details.add(format); - } - if(bitrate != null && bitrate != 0) { - headers.add(R.string.details_cached_bitrate); - details.add(bitrate + " kbps"); - } - if(size != 0) { - headers.add(R.string.details_size); - details.add(Util.formatLocalizedBytes(size, context)); - } - if(duration != null && duration != 0) { - headers.add(R.string.details_length); - details.add(Util.formatDuration(duration)); - } + if(song.getBitRate() != null && song.getBitRate() != 0) { + headers.add(R.string.details_server_bitrate); + details.add(song.getBitRate() + " kbps"); + } + } + if(format != null && !"".equals(format)) { + headers.add(R.string.details_cached_format); + details.add(format); + } + if(bitrate != null && bitrate != 0) { + headers.add(R.string.details_cached_bitrate); + details.add(bitrate + " kbps"); + } + if(size != 0) { + headers.add(R.string.details_size); + details.add(Util.formatLocalizedBytes(size, context)); + } + if(duration != null && duration != 0) { + headers.add(R.string.details_length); + details.add(Util.formatDuration(duration)); + } - try { - Long[] dates = SongDBHandler.getHandler(context).getLastPlayed(song); - if(dates != null && dates[0] != null && dates[0] > 0) { - headers.add(R.string.details_last_played); - Date date = new Date((dates[1] != null && dates[1] > dates[0]) ? dates[1] : dates[0]); - DateFormat dateFormat = DateFormat.getDateInstance(); - details.add(dateFormat.format(date)); - } - } catch(Exception e) { - Log.e(TAG, "Failed to get last played", e); - } + try { + Long[] dates = SongDBHandler.getHandler(context).getLastPlayed(song); + if(dates != null && dates[0] != null && dates[0] > 0) { + headers.add(R.string.details_last_played); + Date date = new Date((dates[1] != null && dates[1] > dates[0]) ? dates[1] : dates[0]); + DateFormat dateFormat = DateFormat.getDateInstance(); + details.add(dateFormat.format(date)); + } + } catch(Exception e) { + Log.e(TAG, "Failed to get last played", e); + } - int title; - if(song.isDirectory()) { - title = R.string.details_title_album; - } else { - title = R.string.details_title_song; - } - Util.showDetailsDialog(context, title, headers, details); - } + int title; + if(song.isDirectory()) { + title = R.string.details_title_album; + } else { + title = R.string.details_title_song; + } + Util.showDetailsDialog(context, title, headers, details); + } - protected boolean entryExists(Entry entry) { - DownloadFile check = new DownloadFile(context, entry, false); - return check.isCompleteFileAvailable(); - } + protected boolean entryExists(Entry entry) { + DownloadFile check = new DownloadFile(context, entry, false); + return check.isCompleteFileAvailable(); + } - public void deleteRecursively(Artist artist) { - deleteRecursively(artist, FileUtil.getArtistDirectory(context, artist)); - } + public void deleteRecursively(Artist artist) { + deleteRecursively(artist, FileUtil.getArtistDirectory(context, artist)); + } - public void deleteRecursively(Entry album) { - deleteRecursively(album, FileUtil.getAlbumDirectory(context, album)); - } + public void deleteRecursively(Entry album) { + deleteRecursively(album, FileUtil.getAlbumDirectory(context, album)); + } - public void deleteRecursively(final Object remove, final File dir) { - if(dir == null) { - return; - } + public void deleteRecursively(final Object remove, final File dir) { + if(dir == null) { + return; + } - new LoadingTask(context) { - @Override - protected Void doInBackground() throws Throwable { - MediaStoreService mediaStore = new MediaStoreService(context); - FileUtil.recursiveDelete(dir, mediaStore); - return null; - } + new LoadingTask(context) { + @Override + protected Void doInBackground() throws Throwable { + MediaStoreService mediaStore = new MediaStoreService(context); + FileUtil.recursiveDelete(dir, mediaStore); + return null; + } - @Override - protected void done(Void result) { - if(Util.isOffline(context)) { - SectionAdapter adapter = getCurrentAdapter(); - if(adapter != null) { - adapter.removeItem(remove); - } else { - refresh(); - } - } else { - UpdateView.triggerUpdate(); - } - } - }.execute(); - } - public void deleteSongs(final List songs) { - new LoadingTask(context) { - @Override - protected Void doInBackground() throws Throwable { - getDownloadService().delete(songs); - return null; - } + @Override + protected void done(Void result) { + if(Util.isOffline(context)) { + SectionAdapter adapter = getCurrentAdapter(); + if(adapter != null) { + adapter.removeItem(remove); + } else { + refresh(); + } + } else { + UpdateView.triggerUpdate(); + } + } + }.execute(); + } + public void deleteSongs(final List songs) { + new LoadingTask(context) { + @Override + protected Void doInBackground() throws Throwable { + getDownloadService().delete(songs); + return null; + } - @Override - protected void done(Void result) { - if(Util.isOffline(context)) { - SectionAdapter adapter = getCurrentAdapter(); - if(adapter != null) { - for(Entry song: songs) { - adapter.removeItem(song); - } - } else { - refresh(); - } - } else { - UpdateView.triggerUpdate(); - } - } - }.execute(); - } + @Override + protected void done(Void result) { + if(Util.isOffline(context)) { + SectionAdapter adapter = getCurrentAdapter(); + if(adapter != null) { + for(Entry song: songs) { + adapter.removeItem(song); + } + } else { + refresh(); + } + } else { + UpdateView.triggerUpdate(); + } + } + }.execute(); + } - public void showAlbumArtist(Entry entry) { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - if(Util.isTagBrowsing(context)) { - args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getArtistId()); - } else { - args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getParent()); - } - args.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getArtist()); - args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); - fragment.setArguments(args); + public void showAlbumArtist(Entry entry) { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + if(Util.isTagBrowsing(context)) { + args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getArtistId()); + } else { + args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getParent()); + } + args.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getArtist()); + args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); + fragment.setArguments(args); - replaceFragment(fragment, true); - } - public void showArtist(Entry entry) { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - if(Util.isTagBrowsing(context)) { - args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getArtistId()); - } else { - if(entry.getGrandParent() == null) { - args.putString(Constants.INTENT_EXTRA_NAME_CHILD_ID, entry.getParent()); - } else { - args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getGrandParent()); - } - } - args.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getArtist()); - args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); - fragment.setArguments(args); + replaceFragment(fragment, true); + } + public void showArtist(Entry entry) { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + if(Util.isTagBrowsing(context)) { + args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getArtistId()); + } else { + if(entry.getGrandParent() == null) { + args.putString(Constants.INTENT_EXTRA_NAME_CHILD_ID, entry.getParent()); + } else { + args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getGrandParent()); + } + } + args.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getArtist()); + args.putBoolean(Constants.INTENT_EXTRA_NAME_ARTIST, true); + fragment.setArguments(args); - replaceFragment(fragment, true); - } + replaceFragment(fragment, true); + } - public void showAlbum(Entry entry) { - SubsonicFragment fragment = new SelectDirectoryFragment(); - Bundle args = new Bundle(); - if(Util.isTagBrowsing(context)) { - args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getAlbumId()); - } else { - args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getParent()); - } - args.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getAlbum()); - fragment.setArguments(args); + public void showAlbum(Entry entry) { + SubsonicFragment fragment = new SelectDirectoryFragment(); + Bundle args = new Bundle(); + if(Util.isTagBrowsing(context)) { + args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getAlbumId()); + } else { + args.putString(Constants.INTENT_EXTRA_NAME_ID, entry.getParent()); + } + args.putString(Constants.INTENT_EXTRA_NAME_NAME, entry.getAlbum()); + fragment.setArguments(args); - replaceFragment(fragment, true); - } + replaceFragment(fragment, true); + } - public GestureDetector getGestureDetector() { - return gestureScanner; - } + public GestureDetector getGestureDetector() { + return gestureScanner; + } - protected void onSongPress(List entries, Entry entry) { - onSongPress(entries, entry, 0, true); - } - protected void onSongPress(List entries, Entry entry, boolean allowPlayAll) { - onSongPress(entries, entry, 0, allowPlayAll); - } - protected void onSongPress(List entries, Entry entry, int position, boolean allowPlayAll) { - List songs = new ArrayList(); + protected void onSongPress(List entries, Entry entry) { + onSongPress(entries, entry, 0, true); + } + protected void onSongPress(List entries, Entry entry, boolean allowPlayAll) { + onSongPress(entries, entry, 0, allowPlayAll); + } + protected void onSongPress(List entries, Entry entry, int position, boolean allowPlayAll) { + List songs = new ArrayList(); - String songPressAction = Util.getSongPressAction(context); - if("all".equals(songPressAction) && allowPlayAll) { - for(Entry song: entries) { - if(!song.isDirectory()) { - songs.add(song); - } - } - playNow(songs, entry, position); - } else if("next".equals(songPressAction)) { - getDownloadService().download(Arrays.asList(entry), false, false, true, false); - } else if("last".equals(songPressAction)) { - getDownloadService().download(Arrays.asList(entry), false, false, false, false); - } else { - songs.add(entry); - playNow(songs); - } - } + String songPressAction = Util.getSongPressAction(context); + if("all".equals(songPressAction) && allowPlayAll) { + for(Entry song: entries) { + if(!song.isDirectory()) { + songs.add(song); + } + } + playNow(songs, entry, position); + } else if("next".equals(songPressAction)) { + getDownloadService().download(Arrays.asList(entry), false, false, true, false); + } else if("last".equals(songPressAction)) { + getDownloadService().download(Arrays.asList(entry), false, false, false, false); + } else { + songs.add(entry); + playNow(songs); + } + } - protected void playNow(List entries) { - playNow(entries, null, null); - } - protected void playNow(final List entries, final String playlistName, final String playlistId) { - new RecursiveLoader(context) { - @Override - protected Boolean doInBackground() throws Throwable { - getSongsRecursively(entries, songs); - return null; - } + protected void playNow(List entries) { + playNow(entries, null, null); + } + protected void playNow(final List entries, final String playlistName, final String playlistId) { + new RecursiveLoader(context) { + @Override + protected Boolean doInBackground() throws Throwable { + getSongsRecursively(entries, songs); + return null; + } - @Override - protected void done(Boolean result) { + @Override + protected void done(Boolean result) { playNow(songs, 0, playlistName, playlistId); - } - }.execute(); - } - protected void playNow(List entries, int position) { - playNow(entries, position, null, null); - } - protected void playNow(List entries, int position, String playlistName, String playlistId) { - Entry selected = entries.isEmpty() ? null : entries.get(0); - playNow(entries, selected, position, playlistName, playlistId); - } + } + }.execute(); + } + protected void playNow(List entries, int position) { + playNow(entries, position, null, null); + } + protected void playNow(List entries, int position, String playlistName, String playlistId) { + Entry selected = entries.isEmpty() ? null : entries.get(0); + playNow(entries, selected, position, playlistName, playlistId); + } - protected void playNow(List entries, Entry song, int position) { - playNow(entries, song, position, null, null); - } + protected void playNow(List entries, Entry song, int position) { + playNow(entries, song, position, null, null); + } - protected void playNow(final List entries, final Entry song, final int position, final String playlistName, final String playlistId) { - new LoadingTask(context) { - @Override - protected Void doInBackground() throws Throwable { - playNowInTask(entries, song, position, playlistName, playlistId); - return null; - } + protected void playNow(final List entries, final Entry song, final int position, final String playlistName, final String playlistId) { + new LoadingTask(context) { + @Override + protected Void doInBackground() throws Throwable { + playNowInTask(entries, song, position, playlistName, playlistId); + return null; + } - @Override - protected void done(Void result) { - context.openNowPlaying(); - } - }.execute(); - } - protected void playNowInTask(final List entries, final Entry song, final int position) { - playNowInTask(entries, song, position, null, null); - } - protected void playNowInTask(final List entries, final Entry song, final int position, final String playlistName, final String playlistId) { - DownloadService downloadService = getDownloadService(); - if(downloadService == null) { - return; - } + @Override + protected void done(Void result) { + context.openNowPlaying(); + } + }.execute(); + } + protected void playNowInTask(final List entries, final Entry song, final int position) { + playNowInTask(entries, song, position, null, null); + } + protected void playNowInTask(final List entries, final Entry song, final int position, final String playlistName, final String playlistId) { + DownloadService downloadService = getDownloadService(); + if(downloadService == null) { + return; + } - downloadService.clear(); - downloadService.download(entries, false, true, true, false, entries.indexOf(song), position); - downloadService.setSuggestedPlaylistName(playlistName, playlistId); - } + downloadService.clear(); + downloadService.download(entries, false, true, true, false, entries.indexOf(song), position); + downloadService.setSuggestedPlaylistName(playlistName, playlistId); + } - public SectionAdapter getCurrentAdapter() { return null; } - public void stopActionMode() { - SectionAdapter adapter = getCurrentAdapter(); - if(adapter != null) { - adapter.stopActionMode(); - } - } - protected void clearSelected() { - if(getCurrentAdapter() != null) { - getCurrentAdapter().clearSelected(); - } - } - protected List getSelectedEntries() { - return getCurrentAdapter().getSelected(); - } + public SectionAdapter getCurrentAdapter() { return null; } + public void stopActionMode() { + SectionAdapter adapter = getCurrentAdapter(); + if(adapter != null) { + adapter.stopActionMode(); + } + } + protected void clearSelected() { + if(getCurrentAdapter() != null) { + getCurrentAdapter().clearSelected(); + } + } + protected List getSelectedEntries() { + return getCurrentAdapter().getSelected(); + } - protected void playNow(final boolean shuffle, final boolean append) { - playNow(shuffle, append, false); - } - protected void playNow(final boolean shuffle, final boolean append, final boolean playNext) { - List songs = getSelectedEntries(); - if(!songs.isEmpty()) { - download(songs, append, false, !append, playNext, shuffle); - clearSelected(); - } - } + protected void playNow(final boolean shuffle, final boolean append) { + playNow(shuffle, append, false); + } + protected void playNow(final boolean shuffle, final boolean append, final boolean playNext) { + List songs = getSelectedEntries(); + if(!songs.isEmpty()) { + download(songs, append, false, !append, playNext, shuffle); + clearSelected(); + } + } - protected void download(List entries, boolean append, boolean save, boolean autoplay, boolean playNext, boolean shuffle) { - download(entries, append, save, autoplay, playNext, shuffle, null, null); - } - protected void download(final List entries, final boolean append, final boolean save, final boolean autoplay, final boolean playNext, final boolean shuffle, final String playlistName, final String playlistId) { - final DownloadService downloadService = getDownloadService(); - if (downloadService == null) { - return; - } - warnIfStorageUnavailable(); + protected void download(List entries, boolean append, boolean save, boolean autoplay, boolean playNext, boolean shuffle) { + download(entries, append, save, autoplay, playNext, shuffle, null, null); + } + protected void download(final List entries, final boolean append, final boolean save, final boolean autoplay, final boolean playNext, final boolean shuffle, final String playlistName, final String playlistId) { + final DownloadService downloadService = getDownloadService(); + if (downloadService == null) { + return; + } + warnIfStorageUnavailable(); - // Conditions for using play now button - if(!append && !save && autoplay && !playNext && !shuffle) { - // Call playNow which goes through and tries to use information - playNow(entries, playlistName, playlistId); - return; - } + // Conditions for using play now button + if(!append && !save && autoplay && !playNext && !shuffle) { + // Call playNow which goes through and tries to use information + playNow(entries, playlistName, playlistId); + return; + } - RecursiveLoader onValid = new RecursiveLoader(context) { - @Override - protected Boolean doInBackground() throws Throwable { - if (!append) { - getDownloadService().clear(); - } - getSongsRecursively(entries, songs); + RecursiveLoader onValid = new RecursiveLoader(context) { + @Override + protected Boolean doInBackground() throws Throwable { + if (!append) { + getDownloadService().clear(); + } + getSongsRecursively(entries, songs); - downloadService.download(songs, save, autoplay, playNext, shuffle); - if (playlistName != null) { - downloadService.setSuggestedPlaylistName(playlistName, playlistId); - } else { - downloadService.setSuggestedPlaylistName(null, null); - } - return null; - } + downloadService.download(songs, save, autoplay, playNext, shuffle); + if (playlistName != null) { + downloadService.setSuggestedPlaylistName(playlistName, playlistId); + } else { + downloadService.setSuggestedPlaylistName(null, null); + } + return null; + } - @Override - protected void done(Boolean result) { - if (autoplay) { - context.openNowPlaying(); - } else if (save) { - Util.toast(context, - context.getResources().getQuantityString(R.plurals.select_album_n_songs_downloading, songs.size(), songs.size())); - } else if (append) { - Util.toast(context, - context.getResources().getQuantityString(R.plurals.select_album_n_songs_added, songs.size(), songs.size())); - } - } - }; + @Override + protected void done(Boolean result) { + if (autoplay) { + context.openNowPlaying(); + } else if (save) { + Util.toast(context, + context.getResources().getQuantityString(R.plurals.select_album_n_songs_downloading, songs.size(), songs.size())); + } else if (append) { + Util.toast(context, + context.getResources().getQuantityString(R.plurals.select_album_n_songs_added, songs.size(), songs.size())); + } + } + }; - executeOnValid(onValid); - } - protected void executeOnValid(RecursiveLoader onValid) { - onValid.execute(); - } - protected void downloadBackground(final boolean save) { - List songs = getSelectedEntries(); - if(!songs.isEmpty()) { - downloadBackground(save, songs); - } - } + executeOnValid(onValid); + } + protected void executeOnValid(RecursiveLoader onValid) { + onValid.execute(); + } + protected void downloadBackground(final boolean save) { + List songs = getSelectedEntries(); + if(!songs.isEmpty()) { + downloadBackground(save, songs); + } + } - protected void downloadBackground(final boolean save, final List entries) { - if (getDownloadService() == null) { - return; - } + protected void downloadBackground(final boolean save, final List entries) { + if (getDownloadService() == null) { + return; + } - warnIfStorageUnavailable(); - new RecursiveLoader(context) { - @Override - protected Boolean doInBackground() throws Throwable { - getSongsRecursively(entries, true); - getDownloadService().downloadBackground(songs, save); - return null; - } + warnIfStorageUnavailable(); + new RecursiveLoader(context) { + @Override + protected Boolean doInBackground() throws Throwable { + getSongsRecursively(entries, true); + getDownloadService().downloadBackground(songs, save); + return null; + } - @Override - protected void done(Boolean result) { - Util.toast(context, context.getResources().getQuantityString(R.plurals.select_album_n_songs_downloading, songs.size(), songs.size())); - } - }.execute(); - } + @Override + protected void done(Boolean result) { + Util.toast(context, context.getResources().getQuantityString(R.plurals.select_album_n_songs_downloading, songs.size(), songs.size())); + } + }.execute(); + } - protected void delete() { - List songs = getSelectedEntries(); - if(!songs.isEmpty()) { - DownloadService downloadService = getDownloadService(); - if(downloadService != null) { - downloadService.delete(songs); - } - } - } + protected void delete() { + List songs = getSelectedEntries(); + if(!songs.isEmpty()) { + DownloadService downloadService = getDownloadService(); + if(downloadService != null) { + downloadService.delete(songs); + } + } + } - protected boolean isShowArtistEnabled() { - return false; - } + protected boolean isShowArtistEnabled() { + return false; + } - protected String getCurrentQuery() { - return null; - } + protected String getCurrentQuery() { + return null; + } - public abstract class RecursiveLoader extends LoadingTask { - protected MusicService musicService; - protected static final int MAX_SONGS = 500; - protected boolean playNowOverride = false; - protected List songs = new ArrayList<>(); + public abstract class RecursiveLoader extends LoadingTask { + protected MusicService musicService; + protected static final int MAX_SONGS = 500; + protected boolean playNowOverride = false; + protected List songs = new ArrayList<>(); - public RecursiveLoader(Activity context) { - super(context); - musicService = MusicServiceFactory.getMusicService(context); - } + public RecursiveLoader(Activity context) { + super(context); + musicService = MusicServiceFactory.getMusicService(context); + } - protected void getSiblingsRecursively(Entry entry) throws Exception { - MusicDirectory parent = new MusicDirectory(); - if(Util.isTagBrowsing(context) && !Util.isOffline(context)) { - parent.setId(entry.getAlbumId()); - } else { - parent.setId(entry.getParent()); - } + protected void getSiblingsRecursively(Entry entry) throws Exception { + MusicDirectory parent = new MusicDirectory(); + if(Util.isTagBrowsing(context) && !Util.isOffline(context)) { + parent.setId(entry.getAlbumId()); + } else { + parent.setId(entry.getParent()); + } - if(parent.getId() == null) { - songs.add(entry); - } else { - MusicDirectory.Entry dir = new Entry(parent.getId()); - dir.setDirectory(true); - parent.addChild(dir); - getSongsRecursively(parent, songs); - } - } - protected void getSongsRecursively(List entry) throws Exception { - getSongsRecursively(entry, false); - } - protected void getSongsRecursively(List entry, boolean allowVideo) throws Exception { - getSongsRecursively(entry, songs, allowVideo); - } - protected void getSongsRecursively(List entry, List songs) throws Exception { - getSongsRecursively(entry, songs, false); - } - protected void getSongsRecursively(List entry, List songs, boolean allowVideo) throws Exception { - MusicDirectory dir = new MusicDirectory(); - dir.addChildren(entry); - getSongsRecursively(dir, songs, allowVideo); - } + if(parent.getId() == null) { + songs.add(entry); + } else { + MusicDirectory.Entry dir = new Entry(parent.getId()); + dir.setDirectory(true); + parent.addChild(dir); + getSongsRecursively(parent, songs); + } + } + protected void getSongsRecursively(List entry) throws Exception { + getSongsRecursively(entry, false); + } + protected void getSongsRecursively(List entry, boolean allowVideo) throws Exception { + getSongsRecursively(entry, songs, allowVideo); + } + protected void getSongsRecursively(List entry, List songs) throws Exception { + getSongsRecursively(entry, songs, false); + } + protected void getSongsRecursively(List entry, List songs, boolean allowVideo) throws Exception { + MusicDirectory dir = new MusicDirectory(); + dir.addChildren(entry); + getSongsRecursively(dir, songs, allowVideo); + } - protected void getSongsRecursively(MusicDirectory parent, List songs) throws Exception { - getSongsRecursively(parent, songs, false); - } - protected void getSongsRecursively(MusicDirectory parent, List songs, boolean allowVideo) throws Exception { - if (songs.size() > MAX_SONGS) { - return; - } + protected void getSongsRecursively(MusicDirectory parent, List songs) throws Exception { + getSongsRecursively(parent, songs, false); + } + protected void getSongsRecursively(MusicDirectory parent, List songs, boolean allowVideo) throws Exception { + if (songs.size() > MAX_SONGS) { + return; + } - for (Entry dir : parent.getChildren(true, false)) { - MusicDirectory musicDirectory; - if(Util.isTagBrowsing(context) && !Util.isOffline(context)) { - musicDirectory = musicService.getAlbum(dir.getId(), dir.getTitle(), false, context, this); - } else { - musicDirectory = musicService.getMusicDirectory(dir.getId(), dir.getTitle(), false, context, this); - } - getSongsRecursively(musicDirectory, songs); - } + for (Entry dir : parent.getChildren(true, false)) { + MusicDirectory musicDirectory; + if(Util.isTagBrowsing(context) && !Util.isOffline(context)) { + musicDirectory = musicService.getAlbum(dir.getId(), dir.getTitle(), false, context, this); + } else { + musicDirectory = musicService.getMusicDirectory(dir.getId(), dir.getTitle(), false, context, this); + } + getSongsRecursively(musicDirectory, songs); + } - for (Entry song : parent.getChildren(false, true)) { + for (Entry song : parent.getChildren(false, true)) { songs.add(song); - } - } + } + } - @Override - protected void done(Boolean result) { - warnIfStorageUnavailable(); + @Override + protected void done(Boolean result) { + warnIfStorageUnavailable(); - if(playNowOverride) { - playNow(songs); - return; - } + if(playNowOverride) { + playNow(songs); + return; + } - if(result) { - context.openNowPlaying(); - } - } - } + if(result) { + context.openNowPlaying(); + } + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/provider/AudinautSearchProvider.java b/app/src/main/java/net/nullsum/audinaut/provider/AudinautSearchProvider.java index 292da06..d15dbad 100644 --- a/app/src/main/java/net/nullsum/audinaut/provider/AudinautSearchProvider.java +++ b/app/src/main/java/net/nullsum/audinaut/provider/AudinautSearchProvider.java @@ -46,164 +46,164 @@ import net.nullsum.audinaut.util.Util; * @author Sindre Mehus */ public class AudinautSearchProvider extends ContentProvider { - private static final String TAG = AudinautSearchProvider.class.getSimpleName(); + private static final String TAG = AudinautSearchProvider.class.getSimpleName(); - private static final String RESOURCE_PREFIX = "android.resource://net.nullsum.audinaut/"; - private static final String[] COLUMNS = {"_id", - SearchManager.SUGGEST_COLUMN_TEXT_1, - SearchManager.SUGGEST_COLUMN_TEXT_2, - SearchManager.SUGGEST_COLUMN_INTENT_DATA, - SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA, - SearchManager.SUGGEST_COLUMN_ICON_1}; + private static final String RESOURCE_PREFIX = "android.resource://net.nullsum.audinaut/"; + private static final String[] COLUMNS = {"_id", + SearchManager.SUGGEST_COLUMN_TEXT_1, + SearchManager.SUGGEST_COLUMN_TEXT_2, + SearchManager.SUGGEST_COLUMN_INTENT_DATA, + SearchManager.SUGGEST_COLUMN_INTENT_EXTRA_DATA, + SearchManager.SUGGEST_COLUMN_ICON_1}; - @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { - if(selectionArgs[0].isEmpty()) { - return null; - } + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { + if(selectionArgs[0].isEmpty()) { + return null; + } - String query = selectionArgs[0] + "*"; - SearchResult searchResult = search(query); - return createCursor(selectionArgs[0], searchResult); - } + String query = selectionArgs[0] + "*"; + SearchResult searchResult = search(query); + return createCursor(selectionArgs[0], searchResult); + } - private SearchResult search(String query) { - MusicService musicService = MusicServiceFactory.getMusicService(getContext()); - if (musicService == null) { - return null; - } + private SearchResult search(String query) { + MusicService musicService = MusicServiceFactory.getMusicService(getContext()); + if (musicService == null) { + return null; + } - try { - return musicService.search(new SearchCritera(query, 5, 10, 10), getContext(), null); - } catch (Exception e) { - return null; - } - } + try { + return musicService.search(new SearchCritera(query, 5, 10, 10), getContext(), null); + } catch (Exception e) { + return null; + } + } - private Cursor createCursor(String query, SearchResult searchResult) { - MatrixCursor cursor = new MatrixCursor(COLUMNS); - if (searchResult == null) { - return cursor; - } - - // Add all results into one pot - List results = new ArrayList(); - results.addAll(searchResult.getArtists()); - results.addAll(searchResult.getAlbums()); - results.addAll(searchResult.getSongs()); - - // For each, calculate its string distance to the query - for(Object obj: results) { - if(obj instanceof Artist) { - Artist artist = (Artist) obj; - artist.setCloseness(Util.getStringDistance(query, artist.getName())); - } else { - MusicDirectory.Entry entry = (MusicDirectory.Entry) obj; - entry.setCloseness(Util.getStringDistance(query, entry.getTitle())); - } - } - - // Sort based on the closeness paramater - Collections.sort(results, new Comparator() { - @Override - public int compare(Object lhs, Object rhs) { - // Get the closeness of the two objects - int left, right; - boolean leftArtist = lhs instanceof Artist; - boolean rightArtist = rhs instanceof Artist; - if (leftArtist) { - left = ((Artist) lhs).getCloseness(); - } else { - left = ((MusicDirectory.Entry) lhs).getCloseness(); - } - if (rightArtist) { - right = ((Artist) rhs).getCloseness(); - } else { - right = ((MusicDirectory.Entry) rhs).getCloseness(); - } + private Cursor createCursor(String query, SearchResult searchResult) { + MatrixCursor cursor = new MatrixCursor(COLUMNS); + if (searchResult == null) { + return cursor; + } - if (left == right) { - if(leftArtist && rightArtist) { - return 0; - } else if(leftArtist) { - return -1; - } else if(rightArtist) { - return 1; - } else { - return 0; - } - } else if (left > right) { - return 1; - } else { - return -1; - } - } - }); - - // Done sorting, add results to cursor - for(Object obj: results) { - if(obj instanceof Artist) { - Artist artist = (Artist) obj; - String icon = RESOURCE_PREFIX + R.drawable.ic_action_artist; - cursor.addRow(new Object[]{artist.getId().hashCode(), artist.getName(), null, "ar-" + artist.getId(), artist.getName(), icon}); - } else { - MusicDirectory.Entry entry = (MusicDirectory.Entry) obj; - - if(entry.isDirectory()) { - String icon = RESOURCE_PREFIX + R.drawable.ic_action_album; - cursor.addRow(new Object[]{entry.getId().hashCode(), entry.getTitle(), entry.getArtist(), entry.getId(), entry.getTitle(), icon}); - } else { - String icon = RESOURCE_PREFIX + R.drawable.ic_action_song; - String id; - if(Util.isTagBrowsing(getContext())) { - id = entry.getAlbumId(); - } else { - id = entry.getParent(); - } + // Add all results into one pot + List results = new ArrayList(); + results.addAll(searchResult.getArtists()); + results.addAll(searchResult.getAlbums()); + results.addAll(searchResult.getSongs()); - String artistDisplay; - if(entry.getArtist() == null) { - if(entry.getAlbum() != null) { - artistDisplay = entry.getAlbumDisplay(); - } else { - artistDisplay = ""; - } - } else if(entry.getAlbum() != null) { - artistDisplay = entry.getArtist() + " - " + entry.getAlbumDisplay(); - } else { - artistDisplay = entry.getArtist(); - } + // For each, calculate its string distance to the query + for(Object obj: results) { + if(obj instanceof Artist) { + Artist artist = (Artist) obj; + artist.setCloseness(Util.getStringDistance(query, artist.getName())); + } else { + MusicDirectory.Entry entry = (MusicDirectory.Entry) obj; + entry.setCloseness(Util.getStringDistance(query, entry.getTitle())); + } + } - cursor.addRow(new Object[]{entry.getId().hashCode(), entry.getTitle(), artistDisplay, "so-" + id, entry.getTitle(), icon}); - } - } - } - return cursor; - } + // Sort based on the closeness paramater + Collections.sort(results, new Comparator() { + @Override + public int compare(Object lhs, Object rhs) { + // Get the closeness of the two objects + int left, right; + boolean leftArtist = lhs instanceof Artist; + boolean rightArtist = rhs instanceof Artist; + if (leftArtist) { + left = ((Artist) lhs).getCloseness(); + } else { + left = ((MusicDirectory.Entry) lhs).getCloseness(); + } + if (rightArtist) { + right = ((Artist) rhs).getCloseness(); + } else { + right = ((MusicDirectory.Entry) rhs).getCloseness(); + } - @Override - public boolean onCreate() { - return false; - } + if (left == right) { + if(leftArtist && rightArtist) { + return 0; + } else if(leftArtist) { + return -1; + } else if(rightArtist) { + return 1; + } else { + return 0; + } + } else if (left > right) { + return 1; + } else { + return -1; + } + } + }); - @Override - public String getType(Uri uri) { - return null; - } + // Done sorting, add results to cursor + for(Object obj: results) { + if(obj instanceof Artist) { + Artist artist = (Artist) obj; + String icon = RESOURCE_PREFIX + R.drawable.ic_action_artist; + cursor.addRow(new Object[]{artist.getId().hashCode(), artist.getName(), null, "ar-" + artist.getId(), artist.getName(), icon}); + } else { + MusicDirectory.Entry entry = (MusicDirectory.Entry) obj; - @Override - public Uri insert(Uri uri, ContentValues contentValues) { - return null; - } + if(entry.isDirectory()) { + String icon = RESOURCE_PREFIX + R.drawable.ic_action_album; + cursor.addRow(new Object[]{entry.getId().hashCode(), entry.getTitle(), entry.getArtist(), entry.getId(), entry.getTitle(), icon}); + } else { + String icon = RESOURCE_PREFIX + R.drawable.ic_action_song; + String id; + if(Util.isTagBrowsing(getContext())) { + id = entry.getAlbumId(); + } else { + id = entry.getParent(); + } - @Override - public int delete(Uri uri, String s, String[] strings) { - return 0; - } + String artistDisplay; + if(entry.getArtist() == null) { + if(entry.getAlbum() != null) { + artistDisplay = entry.getAlbumDisplay(); + } else { + artistDisplay = ""; + } + } else if(entry.getAlbum() != null) { + artistDisplay = entry.getArtist() + " - " + entry.getAlbumDisplay(); + } else { + artistDisplay = entry.getArtist(); + } - @Override - public int update(Uri uri, ContentValues contentValues, String s, String[] strings) { - return 0; - } + cursor.addRow(new Object[]{entry.getId().hashCode(), entry.getTitle(), artistDisplay, "so-" + id, entry.getTitle(), icon}); + } + } + } + return cursor; + } + + @Override + public boolean onCreate() { + return false; + } + + @Override + public String getType(Uri uri) { + return null; + } + + @Override + public Uri insert(Uri uri, ContentValues contentValues) { + return null; + } + + @Override + public int delete(Uri uri, String s, String[] strings) { + return 0; + } + + @Override + public int update(Uri uri, ContentValues contentValues, String s, String[] strings) { + return 0; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x1.java b/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x1.java index d5fb721..3af0b72 100644 --- a/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x1.java +++ b/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x1.java @@ -21,8 +21,8 @@ package net.nullsum.audinaut.provider; import net.nullsum.audinaut.R; public class AudinautWidget4x1 extends AudinautWidgetProvider { - @Override - protected int getLayout() { - return R.layout.appwidget4x1; - } + @Override + protected int getLayout() { + return R.layout.appwidget4x1; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x2.java b/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x2.java index 1149601..9c1f221 100644 --- a/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x2.java +++ b/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x2.java @@ -21,8 +21,8 @@ package net.nullsum.audinaut.provider; import net.nullsum.audinaut.R; public class AudinautWidget4x2 extends AudinautWidgetProvider { - @Override - protected int getLayout() { - return R.layout.appwidget4x2; - } + @Override + protected int getLayout() { + return R.layout.appwidget4x2; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x3.java b/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x3.java index 6f76265..76e1ce5 100644 --- a/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x3.java +++ b/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x3.java @@ -21,8 +21,8 @@ package net.nullsum.audinaut.provider; import net.nullsum.audinaut.R; public class AudinautWidget4x3 extends AudinautWidgetProvider { - @Override - protected int getLayout() { - return R.layout.appwidget4x3; - } + @Override + protected int getLayout() { + return R.layout.appwidget4x3; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x4.java b/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x4.java index d4935d5..3ad9c5b 100644 --- a/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x4.java +++ b/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidget4x4.java @@ -21,8 +21,8 @@ package net.nullsum.audinaut.provider; import net.nullsum.audinaut.R; public class AudinautWidget4x4 extends AudinautWidgetProvider { - @Override - protected int getLayout() { - return R.layout.appwidget4x4; - } + @Override + protected int getLayout() { + return R.layout.appwidget4x4; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidgetProvider.java b/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidgetProvider.java index 4488bab..90a666f 100644 --- a/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidgetProvider.java +++ b/app/src/main/java/net/nullsum/audinaut/provider/AudinautWidgetProvider.java @@ -60,44 +60,44 @@ import net.nullsum.audinaut.util.Util; */ public class AudinautWidgetProvider extends AppWidgetProvider { private static final String TAG = AudinautWidgetProvider.class.getSimpleName(); - private static AudinautWidget4x1 instance4x1; - private static AudinautWidget4x2 instance4x2; - private static AudinautWidget4x3 instance4x3; - private static AudinautWidget4x4 instance4x4; + private static AudinautWidget4x1 instance4x1; + private static AudinautWidget4x2 instance4x2; + private static AudinautWidget4x3 instance4x3; + private static AudinautWidget4x4 instance4x4; - public static synchronized void notifyInstances(Context context, DownloadService service, boolean playing) { - if(instance4x1 == null) { - instance4x1 = new AudinautWidget4x1(); - } - if(instance4x2 == null) { - instance4x2 = new AudinautWidget4x2(); - } - if(instance4x3 == null) { - instance4x3 = new AudinautWidget4x3(); - } - if(instance4x4 == null) { - instance4x4 = new AudinautWidget4x4(); - } - - instance4x1.notifyChange(context, service, playing); - instance4x2.notifyChange(context, service, playing); - instance4x3.notifyChange(context, service, playing); - instance4x4.notifyChange(context, service, playing); - } + public static synchronized void notifyInstances(Context context, DownloadService service, boolean playing) { + if(instance4x1 == null) { + instance4x1 = new AudinautWidget4x1(); + } + if(instance4x2 == null) { + instance4x2 = new AudinautWidget4x2(); + } + if(instance4x3 == null) { + instance4x3 = new AudinautWidget4x3(); + } + if(instance4x4 == null) { + instance4x4 = new AudinautWidget4x4(); + } + + instance4x1.notifyChange(context, service, playing); + instance4x2.notifyChange(context, service, playing); + instance4x3.notifyChange(context, service, playing); + instance4x4.notifyChange(context, service, playing); + } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { defaultAppWidget(context, appWidgetIds); } - - @Override - public void onEnabled(Context context) { - notifyInstances(context, DownloadService.getInstance(), false); - } - - protected int getLayout() { - return 0; - } + + @Override + public void onEnabled(Context context) { + notifyInstances(context, DownloadService.getInstance(), false); + } + + protected int getLayout() { + return 0; + } /** * Initialize given widgets to default state, where we launch Subsonic on default click @@ -108,12 +108,12 @@ public class AudinautWidgetProvider extends AppWidgetProvider { final RemoteViews views = new RemoteViews(context.getPackageName(), getLayout()); views.setTextViewText(R.id.artist, res.getText(R.string.widget_initial_text)); - if(getLayout() == R.layout.appwidget4x2) { - views.setTextViewText(R.id.album, ""); - } + if(getLayout() == R.layout.appwidget4x2) { + views.setTextViewText(R.id.album, ""); + } linkButtons(context, views, false); - performUpdate(context, null, appWidgetIds, false); + performUpdate(context, null, appWidgetIds, false); } private void pushUpdate(Context context, int[] appWidgetIds, RemoteViews views) { @@ -151,20 +151,20 @@ public class AudinautWidgetProvider extends AppWidgetProvider { final Resources res = context.getResources(); final RemoteViews views = new RemoteViews(context.getPackageName(), getLayout()); - if(playing) { - views.setViewVisibility(R.id.widget_root, View.VISIBLE); - } else { - // Hide widget - SharedPreferences prefs = Util.getPreferences(context); - if(prefs.getBoolean(Constants.PREFERENCES_KEY_HIDE_WIDGET, false)) { - views.setViewVisibility(R.id.widget_root, View.GONE); - } - } + if(playing) { + views.setViewVisibility(R.id.widget_root, View.VISIBLE); + } else { + // Hide widget + SharedPreferences prefs = Util.getPreferences(context); + if(prefs.getBoolean(Constants.PREFERENCES_KEY_HIDE_WIDGET, false)) { + views.setViewVisibility(R.id.widget_root, View.GONE); + } + } - // Get Entry from current playing DownloadFile + // Get Entry from current playing DownloadFile MusicDirectory.Entry currentPlaying = null; if(service == null) { - // Deserialize from playling list to setup + // Deserialize from playling list to setup try { PlayerQueue state = FileUtil.deserialize(context, DownloadServiceLifecycleSupport.FILENAME_DOWNLOADS_SER, PlayerQueue.class); if (state != null && state.currentPlayingIndex != -1) { @@ -174,12 +174,12 @@ public class AudinautWidgetProvider extends AppWidgetProvider { Log.e(TAG, "Failed to grab current playing", e); } } else { - currentPlaying = service.getCurrentPlaying() == null ? null : service.getCurrentPlaying().getSong(); + currentPlaying = service.getCurrentPlaying() == null ? null : service.getCurrentPlaying().getSong(); } - + String title = currentPlaying == null ? null : currentPlaying.getTitle(); CharSequence artist = currentPlaying == null ? null : currentPlaying.getArtist(); - CharSequence album = currentPlaying == null ? null : currentPlaying.getAlbum(); + CharSequence album = currentPlaying == null ? null : currentPlaying.getAlbum(); CharSequence errorState = null; // Show error message? @@ -195,19 +195,19 @@ public class AudinautWidgetProvider extends AppWidgetProvider { if (errorState != null) { // Show error state to user - views.setTextViewText(R.id.title,null); + views.setTextViewText(R.id.title,null); views.setTextViewText(R.id.artist, errorState); - views.setTextViewText(R.id.album, ""); - if(getLayout() != R.layout.appwidget4x1) { - views.setImageViewResource(R.id.appwidget_coverart, R.drawable.appwidget_art_default); - } + views.setTextViewText(R.id.album, ""); + if(getLayout() != R.layout.appwidget4x1) { + views.setImageViewResource(R.id.appwidget_coverart, R.drawable.appwidget_art_default); + } } else { // No error, so show normal titles views.setTextViewText(R.id.title, title); views.setTextViewText(R.id.artist, artist); - if(getLayout() != R.layout.appwidget4x1) { - views.setTextViewText(R.id.album, album); - } + if(getLayout() != R.layout.appwidget4x1) { + views.setTextViewText(R.id.album, album); + } } // Set correct drawable for pause state @@ -220,10 +220,10 @@ public class AudinautWidgetProvider extends AppWidgetProvider { // Set the cover art try { boolean large = false; - if(getLayout() != R.layout.appwidget4x1 && getLayout() != R.layout.appwidget4x2) { - large = true; - } - ImageLoader imageLoader = SubsonicActivity.getStaticImageLoader(context); + if(getLayout() != R.layout.appwidget4x1 && getLayout() != R.layout.appwidget4x2) { + large = true; + } + ImageLoader imageLoader = SubsonicActivity.getStaticImageLoader(context); Bitmap bitmap = imageLoader == null ? null : imageLoader.getCachedImage(context, currentPlaying, large); if (bitmap == null) { @@ -243,7 +243,7 @@ public class AudinautWidgetProvider extends AppWidgetProvider { pushUpdate(context, appWidgetIds, views); } - + /** * Round the corners of a bitmap for the cover art image */ @@ -276,29 +276,29 @@ public class AudinautWidgetProvider extends AppWidgetProvider { * @param playerActive @param playerActive True if player is active in background. Launch {@link net.nullsum.audinaut.activity.SubsonicFragmentActivity}. */ private void linkButtons(Context context, RemoteViews views, boolean playerActive) { - Intent intent = new Intent(context, SubsonicFragmentActivity.class); - intent.putExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD, true); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + Intent intent = new Intent(context, SubsonicFragmentActivity.class); + intent.putExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD, true); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.appwidget_coverart, pendingIntent); views.setOnClickPendingIntent(R.id.appwidget_top, pendingIntent); - + // Emulate media button clicks. intent = new Intent("Audinaut.PLAY_PAUSE"); intent.setComponent(new ComponentName(context, DownloadService.class)); - intent.setAction(DownloadService.CMD_TOGGLEPAUSE); + intent.setAction(DownloadService.CMD_TOGGLEPAUSE); pendingIntent = PendingIntent.getService(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.control_play, pendingIntent); intent = new Intent("Audinaut.NEXT"); // Use a unique action name to ensure a different PendingIntent to be created. intent.setComponent(new ComponentName(context, DownloadService.class)); - intent.setAction(DownloadService.CMD_NEXT); + intent.setAction(DownloadService.CMD_NEXT); pendingIntent = PendingIntent.getService(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.control_next, pendingIntent); - + intent = new Intent("Audinaut.PREVIOUS"); // Use a unique action name to ensure a different PendingIntent to be created. intent.setComponent(new ComponentName(context, DownloadService.class)); - intent.setAction(DownloadService.CMD_PREVIOUS); + intent.setAction(DownloadService.CMD_PREVIOUS); pendingIntent = PendingIntent.getService(context, 0, intent, 0); views.setOnClickPendingIntent(R.id.control_previous, pendingIntent); } diff --git a/app/src/main/java/net/nullsum/audinaut/receiver/A2dpIntentReceiver.java b/app/src/main/java/net/nullsum/audinaut/receiver/A2dpIntentReceiver.java index 83422e2..39afb61 100644 --- a/app/src/main/java/net/nullsum/audinaut/receiver/A2dpIntentReceiver.java +++ b/app/src/main/java/net/nullsum/audinaut/receiver/A2dpIntentReceiver.java @@ -7,41 +7,41 @@ import android.util.Log; import net.nullsum.audinaut.service.DownloadService; public class A2dpIntentReceiver extends BroadcastReceiver { - private static final String PLAYSTATUS_RESPONSE = "com.android.music.playstatusresponse"; - private String TAG = A2dpIntentReceiver.class.getSimpleName(); + private static final String PLAYSTATUS_RESPONSE = "com.android.music.playstatusresponse"; + private String TAG = A2dpIntentReceiver.class.getSimpleName(); - @Override - public void onReceive(Context context, Intent intent) { - Log.i(TAG, "GOT INTENT " + intent); + @Override + public void onReceive(Context context, Intent intent) { + Log.i(TAG, "GOT INTENT " + intent); - DownloadService downloadService = DownloadService.getInstance(); + DownloadService downloadService = DownloadService.getInstance(); - if (downloadService != null){ + if (downloadService != null){ - Intent avrcpIntent = new Intent(PLAYSTATUS_RESPONSE); + Intent avrcpIntent = new Intent(PLAYSTATUS_RESPONSE); - avrcpIntent.putExtra("duration", (long) downloadService.getPlayerDuration()); - avrcpIntent.putExtra("position", (long) downloadService.getPlayerPosition()); - avrcpIntent.putExtra("ListSize", (long) downloadService.getSongs().size()); + avrcpIntent.putExtra("duration", (long) downloadService.getPlayerDuration()); + avrcpIntent.putExtra("position", (long) downloadService.getPlayerPosition()); + avrcpIntent.putExtra("ListSize", (long) downloadService.getSongs().size()); - switch (downloadService.getPlayerState()){ - case STARTED: - avrcpIntent.putExtra("playing", true); - break; - case STOPPED: - avrcpIntent.putExtra("playing", false); - break; - case PAUSED: - avrcpIntent.putExtra("playing", false); - break; - case COMPLETED: - avrcpIntent.putExtra("playing", false); - break; - default: - return; - } + switch (downloadService.getPlayerState()){ + case STARTED: + avrcpIntent.putExtra("playing", true); + break; + case STOPPED: + avrcpIntent.putExtra("playing", false); + break; + case PAUSED: + avrcpIntent.putExtra("playing", false); + break; + case COMPLETED: + avrcpIntent.putExtra("playing", false); + break; + default: + return; + } - context.sendBroadcast(avrcpIntent); - } - } -} \ No newline at end of file + context.sendBroadcast(avrcpIntent); + } + } +} diff --git a/app/src/main/java/net/nullsum/audinaut/receiver/AudioNoisyReceiver.java b/app/src/main/java/net/nullsum/audinaut/receiver/AudioNoisyReceiver.java index 733465b..3a62f88 100644 --- a/app/src/main/java/net/nullsum/audinaut/receiver/AudioNoisyReceiver.java +++ b/app/src/main/java/net/nullsum/audinaut/receiver/AudioNoisyReceiver.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.receiver; @@ -28,24 +28,24 @@ import net.nullsum.audinaut.util.Constants; import net.nullsum.audinaut.util.Util; public class AudioNoisyReceiver extends BroadcastReceiver { - private static final String TAG = AudioNoisyReceiver.class.getSimpleName(); + private static final String TAG = AudioNoisyReceiver.class.getSimpleName(); - @Override - public void onReceive(Context context, Intent intent) { - DownloadService downloadService = DownloadService.getInstance(); - // Don't do anything if downloadService is not started - if(downloadService == null) { - return; - } + @Override + public void onReceive(Context context, Intent intent) { + DownloadService downloadService = DownloadService.getInstance(); + // Don't do anything if downloadService is not started + if(downloadService == null) { + return; + } - if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals (intent.getAction ())) { - if((downloadService.getPlayerState() == PlayerState.STARTED || downloadService.getPlayerState() == PlayerState.PAUSED_TEMP)) { - SharedPreferences prefs = Util.getPreferences(downloadService); - int pausePref = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_PAUSE_DISCONNECT, "0")); - if(pausePref == 0) { - downloadService.pause(); - } - } - } - } + if (AudioManager.ACTION_AUDIO_BECOMING_NOISY.equals (intent.getAction ())) { + if((downloadService.getPlayerState() == PlayerState.STARTED || downloadService.getPlayerState() == PlayerState.PAUSED_TEMP)) { + SharedPreferences prefs = Util.getPreferences(downloadService); + int pausePref = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_PAUSE_DISCONNECT, "0")); + if(pausePref == 0) { + downloadService.pause(); + } + } + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/receiver/BootReceiver.java b/app/src/main/java/net/nullsum/audinaut/receiver/BootReceiver.java index 5b0a73a..10d7896 100644 --- a/app/src/main/java/net/nullsum/audinaut/receiver/BootReceiver.java +++ b/app/src/main/java/net/nullsum/audinaut/receiver/BootReceiver.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.receiver; @@ -23,12 +23,12 @@ import net.nullsum.audinaut.service.HeadphoneListenerService; import net.nullsum.audinaut.util.Util; public class BootReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - if(Util.shouldStartOnHeadphones(context)) { - Intent serviceIntent = new Intent(); - serviceIntent.setClassName(context.getPackageName(), HeadphoneListenerService.class.getName()); - context.startService(serviceIntent); - } - } + @Override + public void onReceive(Context context, Intent intent) { + if(Util.shouldStartOnHeadphones(context)) { + Intent serviceIntent = new Intent(); + serviceIntent.setClassName(context.getPackageName(), HeadphoneListenerService.class.getName()); + context.startService(serviceIntent); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/receiver/HeadphonePlugReceiver.java b/app/src/main/java/net/nullsum/audinaut/receiver/HeadphonePlugReceiver.java index 77f799c..0a9ee98 100644 --- a/app/src/main/java/net/nullsum/audinaut/receiver/HeadphonePlugReceiver.java +++ b/app/src/main/java/net/nullsum/audinaut/receiver/HeadphonePlugReceiver.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.receiver; @@ -24,17 +24,17 @@ import net.nullsum.audinaut.service.DownloadService; import net.nullsum.audinaut.util.Util; public class HeadphonePlugReceiver extends BroadcastReceiver { - private static final String TAG = HeadphonePlugReceiver.class.getSimpleName(); + private static final String TAG = HeadphonePlugReceiver.class.getSimpleName(); - @Override - public void onReceive(Context context, Intent intent) { - if(Intent.ACTION_HEADSET_PLUG.equals(intent.getAction())) { - int headphoneState = intent.getIntExtra("state", -1); - if(headphoneState == 1 && Util.shouldStartOnHeadphones(context)) { - Intent start = new Intent(context, DownloadService.class); - start.setAction(DownloadService.START_PLAY); - context.startService(start); - } - } - } + @Override + public void onReceive(Context context, Intent intent) { + if(Intent.ACTION_HEADSET_PLUG.equals(intent.getAction())) { + int headphoneState = intent.getIntExtra("state", -1); + if(headphoneState == 1 && Util.shouldStartOnHeadphones(context)) { + Intent start = new Intent(context, DownloadService.class); + start.setAction(DownloadService.START_PLAY); + context.startService(start); + } + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/receiver/MediaButtonIntentReceiver.java b/app/src/main/java/net/nullsum/audinaut/receiver/MediaButtonIntentReceiver.java index ae36c3d..4480090 100644 --- a/app/src/main/java/net/nullsum/audinaut/receiver/MediaButtonIntentReceiver.java +++ b/app/src/main/java/net/nullsum/audinaut/receiver/MediaButtonIntentReceiver.java @@ -36,22 +36,22 @@ public class MediaButtonIntentReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { KeyEvent event = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT); - if(DownloadService.getInstance() == null && (event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_STOP || - event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)) { - Log.w(TAG, "Ignore keycode event because downloadService is off"); - return; - } + if(DownloadService.getInstance() == null && (event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_STOP || + event.getKeyCode() == KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE || event.getKeyCode() == KeyEvent.KEYCODE_HEADSETHOOK)) { + Log.w(TAG, "Ignore keycode event because downloadService is off"); + return; + } Log.i(TAG, "Got MEDIA_BUTTON key event: " + event); Intent serviceIntent = new Intent(context, DownloadService.class); serviceIntent.putExtra(Intent.EXTRA_KEY_EVENT, event); context.startService(serviceIntent); if (isOrderedBroadcast()) { - try { - abortBroadcast(); - } catch (Exception x) { - // Ignored. - } - } + try { + abortBroadcast(); + } catch (Exception x) { + // Ignored. + } + } } } diff --git a/app/src/main/java/net/nullsum/audinaut/receiver/PlayActionReceiver.java b/app/src/main/java/net/nullsum/audinaut/receiver/PlayActionReceiver.java index c1298a2..ec0e0cc 100644 --- a/app/src/main/java/net/nullsum/audinaut/receiver/PlayActionReceiver.java +++ b/app/src/main/java/net/nullsum/audinaut/receiver/PlayActionReceiver.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.receiver; @@ -25,22 +25,22 @@ import net.nullsum.audinaut.service.DownloadService; import net.nullsum.audinaut.util.Constants; public class PlayActionReceiver extends BroadcastReceiver { - private static final String TAG = PlayActionReceiver.class.getSimpleName(); + private static final String TAG = PlayActionReceiver.class.getSimpleName(); - @Override - public void onReceive(Context context, Intent intent) { - if(intent.hasExtra(Constants.TASKER_EXTRA_BUNDLE)) { - Bundle data = intent.getBundleExtra(Constants.TASKER_EXTRA_BUNDLE); - Boolean startShuffled = data.getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE); + @Override + public void onReceive(Context context, Intent intent) { + if(intent.hasExtra(Constants.TASKER_EXTRA_BUNDLE)) { + Bundle data = intent.getBundleExtra(Constants.TASKER_EXTRA_BUNDLE); + Boolean startShuffled = data.getBoolean(Constants.INTENT_EXTRA_NAME_SHUFFLE); - Intent start = new Intent(context, DownloadService.class); - start.setAction(DownloadService.START_PLAY); - start.putExtra(Constants.INTENT_EXTRA_NAME_SHUFFLE, startShuffled); - start.putExtra(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, data.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR)); - start.putExtra(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, data.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR)); - start.putExtra(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, data.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE)); - start.putExtra(Constants.PREFERENCES_KEY_OFFLINE, data.getInt(Constants.PREFERENCES_KEY_OFFLINE)); - context.startService(start); - } - } + Intent start = new Intent(context, DownloadService.class); + start.setAction(DownloadService.START_PLAY); + start.putExtra(Constants.INTENT_EXTRA_NAME_SHUFFLE, startShuffled); + start.putExtra(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, data.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR)); + start.putExtra(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, data.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR)); + start.putExtra(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, data.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE)); + start.putExtra(Constants.PREFERENCES_KEY_OFFLINE, data.getInt(Constants.PREFERENCES_KEY_OFFLINE)); + context.startService(start); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/service/CachedMusicService.java b/app/src/main/java/net/nullsum/audinaut/service/CachedMusicService.java index 7a67279..d0c204d 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/CachedMusicService.java +++ b/app/src/main/java/net/nullsum/audinaut/service/CachedMusicService.java @@ -56,21 +56,21 @@ import static net.nullsum.audinaut.domain.MusicDirectory.Entry; * @author Sindre Mehus */ public class CachedMusicService implements MusicService { - private static final String TAG = CachedMusicService.class.getSimpleName(); + private static final String TAG = CachedMusicService.class.getSimpleName(); private static final int MUSIC_DIR_CACHE_SIZE = 20; private static final int TTL_MUSIC_DIR = 5 * 60; // Five minutes - public static final int CACHE_UPDATE_LIST = 1; - public static final int CACHE_UPDATE_METADATA = 2; - private static final int CACHED_LAST_FM = 24 * 60; + public static final int CACHE_UPDATE_LIST = 1; + public static final int CACHE_UPDATE_METADATA = 2; + private static final int CACHED_LAST_FM = 24 * 60; - private final RESTMusicService musicService; + private final RESTMusicService musicService; private final TimeLimitedCache cachedIndexes = new TimeLimitedCache(60 * 60, TimeUnit.SECONDS); private final TimeLimitedCache> cachedPlaylists = new TimeLimitedCache>(3600, TimeUnit.SECONDS); private final TimeLimitedCache> cachedMusicFolders = new TimeLimitedCache>(10 * 3600, TimeUnit.SECONDS); private String restUrl; - private String musicFolderId; - private boolean isTagBrowsing = false; + private String musicFolderId; + private boolean isTagBrowsing = false; public CachedMusicService(RESTMusicService musicService) { this.musicService = musicService; @@ -90,22 +90,22 @@ public class CachedMusicService implements MusicService { } List result = cachedMusicFolders.get(); if (result == null) { - if(!refresh) { - result = FileUtil.deserialize(context, getCacheName(context, "musicFolders"), ArrayList.class); - } + if(!refresh) { + result = FileUtil.deserialize(context, getCacheName(context, "musicFolders"), ArrayList.class); + } - if(result == null) { - result = musicService.getMusicFolders(refresh, context, progressListener); - FileUtil.serialize(context, new ArrayList(result), getCacheName(context, "musicFolders")); - } + if(result == null) { + result = musicService.getMusicFolders(refresh, context, progressListener); + FileUtil.serialize(context, new ArrayList(result), getCacheName(context, "musicFolders")); + } - MusicFolder.sort(result); + MusicFolder.sort(result); cachedMusicFolders.set(result); } return result; } - @Override + @Override public Indexes getIndexes(String musicFolderId, boolean refresh, Context context, ProgressListener progressListener) throws Exception { checkSettingsChanged(context); if (refresh) { @@ -114,16 +114,16 @@ public class CachedMusicService implements MusicService { } Indexes result = cachedIndexes.get(); if (result == null) { - String name = Util.isTagBrowsing(context, musicService.getInstance(context)) ? "artists" : "indexes"; - name = getCacheName(context, name, musicFolderId); - if(!refresh) { - result = FileUtil.deserialize(context, name, Indexes.class); - } + String name = Util.isTagBrowsing(context, musicService.getInstance(context)) ? "artists" : "indexes"; + name = getCacheName(context, name, musicFolderId); + if(!refresh) { + result = FileUtil.deserialize(context, name, Indexes.class); + } - if(result == null) { - result = musicService.getIndexes(musicFolderId, refresh, context, progressListener); - FileUtil.serialize(context, result, name); - } + if(result == null) { + result = musicService.getIndexes(musicFolderId, refresh, context, progressListener); + FileUtil.serialize(context, result, name); + } cachedIndexes.set(result); } return result; @@ -131,182 +131,182 @@ public class CachedMusicService implements MusicService { @Override public MusicDirectory getMusicDirectory(final String id, final String name, final boolean refresh, final Context context, final ProgressListener progressListener) throws Exception { - MusicDirectory dir = null; - final MusicDirectory cached = FileUtil.deserialize(context, getCacheName(context, "directory", id), MusicDirectory.class); - if(!refresh && cached != null) { - dir = cached; + MusicDirectory dir = null; + final MusicDirectory cached = FileUtil.deserialize(context, getCacheName(context, "directory", id), MusicDirectory.class); + if(!refresh && cached != null) { + dir = cached; - new SilentBackgroundTask(context) { - MusicDirectory refreshed; - private boolean metadataUpdated; + new SilentBackgroundTask(context) { + MusicDirectory refreshed; + private boolean metadataUpdated; - @Override - protected Void doInBackground() throws Throwable { - refreshed = musicService.getMusicDirectory(id, name, true, context, null); - updateAllSongs(context, refreshed); - metadataUpdated = cached.updateMetadata(refreshed); - deleteRemovedEntries(context, refreshed, cached); - FileUtil.serialize(context, refreshed, getCacheName(context, "directory", id)); - return null; - } + @Override + protected Void doInBackground() throws Throwable { + refreshed = musicService.getMusicDirectory(id, name, true, context, null); + updateAllSongs(context, refreshed); + metadataUpdated = cached.updateMetadata(refreshed); + deleteRemovedEntries(context, refreshed, cached); + FileUtil.serialize(context, refreshed, getCacheName(context, "directory", id)); + return null; + } - // Update which entries exist - @Override - public void done(Void result) { - if(progressListener != null) { - if(cached.updateEntriesList(context, musicService.getInstance(context), refreshed)) { - progressListener.updateCache(CACHE_UPDATE_LIST); - } - if(metadataUpdated) { - progressListener.updateCache(CACHE_UPDATE_METADATA); - } - } - } + // Update which entries exist + @Override + public void done(Void result) { + if(progressListener != null) { + if(cached.updateEntriesList(context, musicService.getInstance(context), refreshed)) { + progressListener.updateCache(CACHE_UPDATE_LIST); + } + if(metadataUpdated) { + progressListener.updateCache(CACHE_UPDATE_METADATA); + } + } + } - @Override - public void error(Throwable error) { - Log.e(TAG, "Failed to refresh music directory", error); - } - }.execute(); - } + @Override + public void error(Throwable error) { + Log.e(TAG, "Failed to refresh music directory", error); + } + }.execute(); + } - if(dir == null) { - dir = musicService.getMusicDirectory(id, name, refresh, context, progressListener); - updateAllSongs(context, dir); - FileUtil.serialize(context, dir, getCacheName(context, "directory", id)); + if(dir == null) { + dir = musicService.getMusicDirectory(id, name, refresh, context, progressListener); + updateAllSongs(context, dir); + FileUtil.serialize(context, dir, getCacheName(context, "directory", id)); - // If a cached copy exists to check against, look for removes - deleteRemovedEntries(context, dir, cached); - } - dir.sortChildren(context, musicService.getInstance(context)); + // If a cached copy exists to check against, look for removes + deleteRemovedEntries(context, dir, cached); + } + dir.sortChildren(context, musicService.getInstance(context)); - return dir; + return dir; } - @Override - public MusicDirectory getArtist(final String id, final String name, final boolean refresh, final Context context, final ProgressListener progressListener) throws Exception { - MusicDirectory dir = null; - final MusicDirectory cached = FileUtil.deserialize(context, getCacheName(context, "artist", id), MusicDirectory.class); - if(!refresh && cached != null) { - dir = cached; + @Override + public MusicDirectory getArtist(final String id, final String name, final boolean refresh, final Context context, final ProgressListener progressListener) throws Exception { + MusicDirectory dir = null; + final MusicDirectory cached = FileUtil.deserialize(context, getCacheName(context, "artist", id), MusicDirectory.class); + if(!refresh && cached != null) { + dir = cached; - new SilentBackgroundTask(context) { - MusicDirectory refreshed; + new SilentBackgroundTask(context) { + MusicDirectory refreshed; - @Override - protected Void doInBackground() throws Throwable { - refreshed = musicService.getArtist(id, name, refresh, context, null); - cached.updateMetadata(refreshed); - deleteRemovedEntries(context, refreshed, cached); - FileUtil.serialize(context, refreshed, getCacheName(context, "artist", id)); - return null; - } + @Override + protected Void doInBackground() throws Throwable { + refreshed = musicService.getArtist(id, name, refresh, context, null); + cached.updateMetadata(refreshed); + deleteRemovedEntries(context, refreshed, cached); + FileUtil.serialize(context, refreshed, getCacheName(context, "artist", id)); + return null; + } - // Update which entries exist - @Override - public void done(Void result) { - if(progressListener != null) { - if(cached.updateEntriesList(context, musicService.getInstance(context), refreshed)) { - progressListener.updateCache(CACHE_UPDATE_LIST); - } - } - } + // Update which entries exist + @Override + public void done(Void result) { + if(progressListener != null) { + if(cached.updateEntriesList(context, musicService.getInstance(context), refreshed)) { + progressListener.updateCache(CACHE_UPDATE_LIST); + } + } + } - @Override - public void error(Throwable error) { - Log.e(TAG, "Failed to refresh getArtist", error); - } - }.execute(); - } + @Override + public void error(Throwable error) { + Log.e(TAG, "Failed to refresh getArtist", error); + } + }.execute(); + } - if(dir == null) { - dir = musicService.getArtist(id, name, refresh, context, progressListener); - FileUtil.serialize(context, dir, getCacheName(context, "artist", id)); + if(dir == null) { + dir = musicService.getArtist(id, name, refresh, context, progressListener); + FileUtil.serialize(context, dir, getCacheName(context, "artist", id)); - // If a cached copy exists to check against, look for removes - deleteRemovedEntries(context, dir, cached); - } - dir.sortChildren(context, musicService.getInstance(context)); + // If a cached copy exists to check against, look for removes + deleteRemovedEntries(context, dir, cached); + } + dir.sortChildren(context, musicService.getInstance(context)); - return dir; - } + return dir; + } - @Override - public MusicDirectory getAlbum(final String id, final String name, final boolean refresh, final Context context, final ProgressListener progressListener) throws Exception { - MusicDirectory dir = null; - final MusicDirectory cached = FileUtil.deserialize(context, getCacheName(context, "album", id), MusicDirectory.class); - if(!refresh && cached != null) { - dir = cached; + @Override + public MusicDirectory getAlbum(final String id, final String name, final boolean refresh, final Context context, final ProgressListener progressListener) throws Exception { + MusicDirectory dir = null; + final MusicDirectory cached = FileUtil.deserialize(context, getCacheName(context, "album", id), MusicDirectory.class); + if(!refresh && cached != null) { + dir = cached; - new SilentBackgroundTask(context) { - MusicDirectory refreshed; - private boolean metadataUpdated; + new SilentBackgroundTask(context) { + MusicDirectory refreshed; + private boolean metadataUpdated; - @Override - protected Void doInBackground() throws Throwable { - refreshed = musicService.getAlbum(id, name, refresh, context, null); - updateAllSongs(context, refreshed); - metadataUpdated = cached.updateMetadata(refreshed); - deleteRemovedEntries(context, refreshed, cached); - FileUtil.serialize(context, refreshed, getCacheName(context, "album", id)); - return null; - } + @Override + protected Void doInBackground() throws Throwable { + refreshed = musicService.getAlbum(id, name, refresh, context, null); + updateAllSongs(context, refreshed); + metadataUpdated = cached.updateMetadata(refreshed); + deleteRemovedEntries(context, refreshed, cached); + FileUtil.serialize(context, refreshed, getCacheName(context, "album", id)); + return null; + } - // Update which entries exist - @Override - public void done(Void result) { - if(progressListener != null) { - if(cached.updateEntriesList(context, musicService.getInstance(context), refreshed)) { - progressListener.updateCache(CACHE_UPDATE_LIST); - } - if(metadataUpdated) { - progressListener.updateCache(CACHE_UPDATE_METADATA); - } - } - } + // Update which entries exist + @Override + public void done(Void result) { + if(progressListener != null) { + if(cached.updateEntriesList(context, musicService.getInstance(context), refreshed)) { + progressListener.updateCache(CACHE_UPDATE_LIST); + } + if(metadataUpdated) { + progressListener.updateCache(CACHE_UPDATE_METADATA); + } + } + } - @Override - public void error(Throwable error) { - Log.e(TAG, "Failed to refresh getAlbum", error); - } - }.execute(); - } + @Override + public void error(Throwable error) { + Log.e(TAG, "Failed to refresh getAlbum", error); + } + }.execute(); + } - if(dir == null) { - dir = musicService.getAlbum(id, name, refresh, context, progressListener); - updateAllSongs(context, dir); - FileUtil.serialize(context, dir, getCacheName(context, "album", id)); + if(dir == null) { + dir = musicService.getAlbum(id, name, refresh, context, progressListener); + updateAllSongs(context, dir); + FileUtil.serialize(context, dir, getCacheName(context, "album", id)); - // If a cached copy exists to check against, look for removes - deleteRemovedEntries(context, dir, cached); - } - dir.sortChildren(context, musicService.getInstance(context)); + // If a cached copy exists to check against, look for removes + deleteRemovedEntries(context, dir, cached); + } + dir.sortChildren(context, musicService.getInstance(context)); - return dir; - } + return dir; + } - @Override + @Override public SearchResult search(SearchCritera criteria, Context context, ProgressListener progressListener) throws Exception { return musicService.search(criteria, context, progressListener); } @Override public MusicDirectory getPlaylist(boolean refresh, String id, String name, Context context, ProgressListener progressListener) throws Exception { - MusicDirectory dir = null; - MusicDirectory cachedPlaylist = FileUtil.deserialize(context, getCacheName(context, "playlist", id), MusicDirectory.class); - if(!refresh) { - dir = cachedPlaylist; - } - if(dir == null) { - dir = musicService.getPlaylist(refresh, id, name, context, progressListener); - updateAllSongs(context, dir); - FileUtil.serialize(context, dir, getCacheName(context, "playlist", id)); + MusicDirectory dir = null; + MusicDirectory cachedPlaylist = FileUtil.deserialize(context, getCacheName(context, "playlist", id), MusicDirectory.class); + if(!refresh) { + dir = cachedPlaylist; + } + if(dir == null) { + dir = musicService.getPlaylist(refresh, id, name, context, progressListener); + updateAllSongs(context, dir); + FileUtil.serialize(context, dir, getCacheName(context, "playlist", id)); - File playlistFile = FileUtil.getPlaylistFile(context, Util.getServerName(context, musicService.getInstance(context)), dir.getName()); - if(cachedPlaylist == null || !playlistFile.exists() || !cachedPlaylist.getChildren().equals(dir.getChildren())) { - FileUtil.writePlaylistFile(context, playlistFile, dir); - } - } + File playlistFile = FileUtil.getPlaylistFile(context, Util.getServerName(context, musicService.getInstance(context)), dir.getName()); + if(cachedPlaylist == null || !playlistFile.exists() || !cachedPlaylist.getChildren().equals(dir.getChildren())) { + FileUtil.writePlaylistFile(context, playlistFile, dir); + } + } return dir; } @@ -315,14 +315,14 @@ public class CachedMusicService implements MusicService { checkSettingsChanged(context); List result = refresh ? null : cachedPlaylists.get(); if (result == null) { - if(!refresh) { - result = FileUtil.deserialize(context, getCacheName(context, "playlist"), ArrayList.class); - } - - if(result == null) { - result = musicService.getPlaylists(refresh, context, progressListener); - FileUtil.serialize(context, new ArrayList(result), getCacheName(context, "playlist")); - } + if(!refresh) { + result = FileUtil.deserialize(context, getCacheName(context, "playlist"), ArrayList.class); + } + + if(result == null) { + result = musicService.getPlaylists(refresh, context, progressListener); + FileUtil.serialize(context, new ArrayList(result), getCacheName(context, "playlist")); + } cachedPlaylists.set(result); } return result; @@ -330,272 +330,272 @@ public class CachedMusicService implements MusicService { @Override public void createPlaylist(String id, String name, List entries, Context context, ProgressListener progressListener) throws Exception { - cachedPlaylists.clear(); - Util.delete(new File(context.getCacheDir(), getCacheName(context, "playlist"))); + cachedPlaylists.clear(); + Util.delete(new File(context.getCacheDir(), getCacheName(context, "playlist"))); musicService.createPlaylist(id, name, entries, context, progressListener); } - - @Override - public void deletePlaylist(final String id, Context context, ProgressListener progressListener) throws Exception { - musicService.deletePlaylist(id, context, progressListener); - new PlaylistUpdater(context, id) { - @Override - public void updateResult(List objects, Playlist result) { - objects.remove(result); - cachedPlaylists.set(objects); - } - }.execute(); - } - - @Override - public void addToPlaylist(String id, final List toAdd, Context context, ProgressListener progressListener) throws Exception { - musicService.addToPlaylist(id, toAdd, context, progressListener); + @Override + public void deletePlaylist(final String id, Context context, ProgressListener progressListener) throws Exception { + musicService.deletePlaylist(id, context, progressListener); - new MusicDirectoryUpdater(context, "playlist", id) { - @Override - public boolean checkResult(Entry check) { - return true; - } + new PlaylistUpdater(context, id) { + @Override + public void updateResult(List objects, Playlist result) { + objects.remove(result); + cachedPlaylists.set(objects); + } + }.execute(); + } - @Override - public void updateResult(List objects, Entry result) { - objects.addAll(toAdd); - } - }.execute(); - } - - @Override - public void removeFromPlaylist(final String id, final List toRemove, Context context, ProgressListener progressListener) throws Exception { - musicService.removeFromPlaylist(id, toRemove, context, progressListener); + @Override + public void addToPlaylist(String id, final List toAdd, Context context, ProgressListener progressListener) throws Exception { + musicService.addToPlaylist(id, toAdd, context, progressListener); - new MusicDirectoryUpdater(context, "playlist", id) { - @Override - public boolean checkResult(Entry check) { - return true; - } + new MusicDirectoryUpdater(context, "playlist", id) { + @Override + public boolean checkResult(Entry check) { + return true; + } - @Override - public void updateResult(List objects, Entry result) { - // Make sure this playlist is supposed to be synced - boolean supposedToUnpin = false; + @Override + public void updateResult(List objects, Entry result) { + objects.addAll(toAdd); + } + }.execute(); + } - // Remove in reverse order so indexes are still correct as we iterate through - for(ListIterator iterator = toRemove.listIterator(toRemove.size()); iterator.hasPrevious(); ) { - int index = iterator.previous(); - if(supposedToUnpin) { - Entry entry = objects.get(index); - DownloadFile file = new DownloadFile(context, entry, true); - file.unpin(); - } + @Override + public void removeFromPlaylist(final String id, final List toRemove, Context context, ProgressListener progressListener) throws Exception { + musicService.removeFromPlaylist(id, toRemove, context, progressListener); - objects.remove(index); - } - } - }.execute(); - } - - @Override - public void overwritePlaylist(String id, String name, int toRemove, final List toAdd, Context context, ProgressListener progressListener) throws Exception { - musicService.overwritePlaylist(id, name, toRemove, toAdd, context, progressListener); + new MusicDirectoryUpdater(context, "playlist", id) { + @Override + public boolean checkResult(Entry check) { + return true; + } - new MusicDirectoryUpdater(context, "playlist", id) { - @Override - public boolean checkResult(Entry check) { - return true; - } + @Override + public void updateResult(List objects, Entry result) { + // Make sure this playlist is supposed to be synced + boolean supposedToUnpin = false; - @Override - public void updateResult(List objects, Entry result) { - objects.clear(); - objects.addAll(toAdd); - } - }.execute(); - } - - @Override - public void updatePlaylist(String id, final String name, final String comment, final boolean pub, Context context, ProgressListener progressListener) throws Exception { - musicService.updatePlaylist(id, name, comment, pub, context, progressListener); + // Remove in reverse order so indexes are still correct as we iterate through + for(ListIterator iterator = toRemove.listIterator(toRemove.size()); iterator.hasPrevious(); ) { + int index = iterator.previous(); + if(supposedToUnpin) { + Entry entry = objects.get(index); + DownloadFile file = new DownloadFile(context, entry, true); + file.unpin(); + } - new PlaylistUpdater(context, id) { - @Override - public void updateResult(List objects, Playlist result) { - result.setName(name); - result.setComment(comment); - result.setPublic(pub); + objects.remove(index); + } + } + }.execute(); + } - cachedPlaylists.set(objects); - } - }.execute(); - } + @Override + public void overwritePlaylist(String id, String name, int toRemove, final List toAdd, Context context, ProgressListener progressListener) throws Exception { + musicService.overwritePlaylist(id, name, toRemove, toAdd, context, progressListener); - @Override - public MusicDirectory getAlbumList(String type, int size, int offset, boolean refresh, Context context, ProgressListener progressListener) throws Exception { - try { - MusicDirectory dir = musicService.getAlbumList(type, size, offset, refresh, context, progressListener); + new MusicDirectoryUpdater(context, "playlist", id) { + @Override + public boolean checkResult(Entry check) { + return true; + } - // Do some serialization updates for changes to recently added - if ("newest".equals(type) && offset == 0) { - String recentlyAddedFile = getCacheName(context, type); - ArrayList recents = FileUtil.deserialize(context, recentlyAddedFile, ArrayList.class); - if (recents == null) { - recents = new ArrayList(); - } + @Override + public void updateResult(List objects, Entry result) { + objects.clear(); + objects.addAll(toAdd); + } + }.execute(); + } - // Add any new items - final int instance = musicService.getInstance(context); - isTagBrowsing = Util.isTagBrowsing(context, instance); - for (final Entry album : dir.getChildren()) { - if (!recents.contains(album.getId())) { - recents.add(album.getId()); + @Override + public void updatePlaylist(String id, final String name, final String comment, final boolean pub, Context context, ProgressListener progressListener) throws Exception { + musicService.updatePlaylist(id, name, comment, pub, context, progressListener); - String cacheName, parent; - if (isTagBrowsing) { - cacheName = "artist"; - parent = album.getArtistId(); - } else { - cacheName = "directory"; - parent = album.getParent(); - } + new PlaylistUpdater(context, id) { + @Override + public void updateResult(List objects, Playlist result) { + result.setName(name); + result.setComment(comment); + result.setPublic(pub); - // Add album to artist - if (parent != null) { - new MusicDirectoryUpdater(context, cacheName, parent) { - private boolean changed = false; + cachedPlaylists.set(objects); + } + }.execute(); + } - @Override - public boolean checkResult(Entry check) { - return true; - } + @Override + public MusicDirectory getAlbumList(String type, int size, int offset, boolean refresh, Context context, ProgressListener progressListener) throws Exception { + try { + MusicDirectory dir = musicService.getAlbumList(type, size, offset, refresh, context, progressListener); - @Override - public void updateResult(List objects, Entry result) { - // Only add if it doesn't already exist in it! - if (!objects.contains(album)) { - objects.add(album); - changed = true; - } - } + // Do some serialization updates for changes to recently added + if ("newest".equals(type) && offset == 0) { + String recentlyAddedFile = getCacheName(context, type); + ArrayList recents = FileUtil.deserialize(context, recentlyAddedFile, ArrayList.class); + if (recents == null) { + recents = new ArrayList(); + } - @Override - public void save(ArrayList objects) { - // Only save if actually added to artist - if (changed) { - musicDirectory.replaceChildren(objects); - FileUtil.serialize(context, musicDirectory, cacheName); - } - } - }.execute(); - } else { - // If parent is null, then this is a root level album - final Artist artist = new Artist(); - artist.setId(album.getId()); - artist.setName(album.getTitle()); + // Add any new items + final int instance = musicService.getInstance(context); + isTagBrowsing = Util.isTagBrowsing(context, instance); + for (final Entry album : dir.getChildren()) { + if (!recents.contains(album.getId())) { + recents.add(album.getId()); - new IndexesUpdater(context, isTagBrowsing ? "artists" : "indexes") { - private boolean changed = false; + String cacheName, parent; + if (isTagBrowsing) { + cacheName = "artist"; + parent = album.getArtistId(); + } else { + cacheName = "directory"; + parent = album.getParent(); + } - @Override - public boolean checkResult(Artist check) { - return true; - } + // Add album to artist + if (parent != null) { + new MusicDirectoryUpdater(context, cacheName, parent) { + private boolean changed = false; - @Override - public void updateResult(List objects, Artist result) { - if (!objects.contains(artist)) { - objects.add(artist); - changed = true; - } - } + @Override + public boolean checkResult(Entry check) { + return true; + } - @Override - public void save(ArrayList objects) { - if (changed) { - indexes.setArtists(objects); - FileUtil.serialize(context, indexes, cacheName); - cachedIndexes.set(indexes); - } - } - }.execute(); - } - } - } + @Override + public void updateResult(List objects, Entry result) { + // Only add if it doesn't already exist in it! + if (!objects.contains(album)) { + objects.add(album); + changed = true; + } + } - // Keep list from growing into infinity - while (recents.size() > 0) { - recents.remove(0); - } - FileUtil.serialize(context, recents, recentlyAddedFile); - } + @Override + public void save(ArrayList objects) { + // Only save if actually added to artist + if (changed) { + musicDirectory.replaceChildren(objects); + FileUtil.serialize(context, musicDirectory, cacheName); + } + } + }.execute(); + } else { + // If parent is null, then this is a root level album + final Artist artist = new Artist(); + artist.setId(album.getId()); + artist.setName(album.getTitle()); - FileUtil.serialize(context, dir, getCacheName(context, type, Integer.toString(offset))); - return dir; - } catch(IOException e) { - Log.w(TAG, "Failed to refresh album list: ", e); - if(refresh) { - throw e; - } + new IndexesUpdater(context, isTagBrowsing ? "artists" : "indexes") { + private boolean changed = false; - MusicDirectory dir = FileUtil.deserialize(context, getCacheName(context, type, Integer.toString(offset)), MusicDirectory.class); + @Override + public boolean checkResult(Artist check) { + return true; + } - if(dir == null) { - // If we are at start and no cache, throw error higher - if(offset == 0) { - throw e; - } else { - // Otherwise just pretend we are at the end of the list - return new MusicDirectory(); - } - } else { - return dir; - } - } - } + @Override + public void updateResult(List objects, Artist result) { + if (!objects.contains(artist)) { + objects.add(artist); + changed = true; + } + } - @Override - public MusicDirectory getAlbumList(String type, String extra, int size, int offset, boolean refresh, Context context, ProgressListener progressListener) throws Exception { - try { - MusicDirectory dir = musicService.getAlbumList(type, extra, size, offset, refresh, context, progressListener); - FileUtil.serialize(context, dir, getCacheName(context, type + extra, Integer.toString(offset))); - return dir; - } catch(IOException e) { - Log.w(TAG, "Failed to refresh album list: ", e); - if(refresh) { - throw e; - } + @Override + public void save(ArrayList objects) { + if (changed) { + indexes.setArtists(objects); + FileUtil.serialize(context, indexes, cacheName); + cachedIndexes.set(indexes); + } + } + }.execute(); + } + } + } - MusicDirectory dir = FileUtil.deserialize(context, getCacheName(context, type + extra, Integer.toString(offset)), MusicDirectory.class); + // Keep list from growing into infinity + while (recents.size() > 0) { + recents.remove(0); + } + FileUtil.serialize(context, recents, recentlyAddedFile); + } - if(dir == null) { - // If we are at start and no cache, throw error higher - if(offset == 0) { - throw e; - } else { - // Otherwise just pretend we are at the end of the list - return new MusicDirectory(); - } - } else { - return dir; - } - } - } + FileUtil.serialize(context, dir, getCacheName(context, type, Integer.toString(offset))); + return dir; + } catch(IOException e) { + Log.w(TAG, "Failed to refresh album list: ", e); + if(refresh) { + throw e; + } - @Override - public MusicDirectory getSongList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception { - return musicService.getSongList(type, size, offset, context, progressListener); - } + MusicDirectory dir = FileUtil.deserialize(context, getCacheName(context, type, Integer.toString(offset)), MusicDirectory.class); - @Override - public MusicDirectory getRandomSongs(int size, String artistId, Context context, ProgressListener progressListener) throws Exception { - return musicService.getRandomSongs(size, artistId, context, progressListener); - } + if(dir == null) { + // If we are at start and no cache, throw error higher + if(offset == 0) { + throw e; + } else { + // Otherwise just pretend we are at the end of the list + return new MusicDirectory(); + } + } else { + return dir; + } + } + } + + @Override + public MusicDirectory getAlbumList(String type, String extra, int size, int offset, boolean refresh, Context context, ProgressListener progressListener) throws Exception { + try { + MusicDirectory dir = musicService.getAlbumList(type, extra, size, offset, refresh, context, progressListener); + FileUtil.serialize(context, dir, getCacheName(context, type + extra, Integer.toString(offset))); + return dir; + } catch(IOException e) { + Log.w(TAG, "Failed to refresh album list: ", e); + if(refresh) { + throw e; + } + + MusicDirectory dir = FileUtil.deserialize(context, getCacheName(context, type + extra, Integer.toString(offset)), MusicDirectory.class); + + if(dir == null) { + // If we are at start and no cache, throw error higher + if(offset == 0) { + throw e; + } else { + // Otherwise just pretend we are at the end of the list + return new MusicDirectory(); + } + } else { + return dir; + } + } + } + + @Override + public MusicDirectory getSongList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception { + return musicService.getSongList(type, size, offset, context, progressListener); + } + + @Override + public MusicDirectory getRandomSongs(int size, String artistId, Context context, ProgressListener progressListener) throws Exception { + return musicService.getRandomSongs(size, artistId, context, progressListener); + } @Override public MusicDirectory getRandomSongs(int size, String folder, String genre, String startYear, String endYear, Context context, ProgressListener progressListener) throws Exception { return musicService.getRandomSongs(size, folder, genre, startYear, endYear, context, progressListener); } - @Override + @Override public Bitmap getCoverArt(Context context, Entry entry, int size, ProgressListener progressListener, SilentBackgroundTask task) throws Exception { return musicService.getCoverArt(context, entry, size, progressListener, task); } @@ -605,428 +605,428 @@ public class CachedMusicService implements MusicService { return musicService.getDownloadInputStream(context, song, offset, maxBitrate, task); } - @Override - public List getGenres(boolean refresh, Context context, ProgressListener progressListener) throws Exception { - List result = null; + @Override + public List getGenres(boolean refresh, Context context, ProgressListener progressListener) throws Exception { + List result = null; - if(!refresh) { - result = FileUtil.deserialize(context, getCacheName(context, "genre"), ArrayList.class); - } + if(!refresh) { + result = FileUtil.deserialize(context, getCacheName(context, "genre"), ArrayList.class); + } - if(result == null) { - result = musicService.getGenres(refresh, context, progressListener); - FileUtil.serialize(context, new ArrayList(result), getCacheName(context, "genre")); - } + if(result == null) { + result = musicService.getGenres(refresh, context, progressListener); + FileUtil.serialize(context, new ArrayList(result), getCacheName(context, "genre")); + } - return result; - } + return result; + } - @Override - public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception { - try { - MusicDirectory dir = musicService.getSongsByGenre(genre, count, offset, context, progressListener); - FileUtil.serialize(context, dir, getCacheName(context, "genreSongs", Integer.toString(offset))); + @Override + public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception { + try { + MusicDirectory dir = musicService.getSongsByGenre(genre, count, offset, context, progressListener); + FileUtil.serialize(context, dir, getCacheName(context, "genreSongs", Integer.toString(offset))); - return dir; - } catch(IOException e) { - MusicDirectory dir = FileUtil.deserialize(context, getCacheName(context, "genreSongs", Integer.toString(offset)), MusicDirectory.class); + return dir; + } catch(IOException e) { + MusicDirectory dir = FileUtil.deserialize(context, getCacheName(context, "genreSongs", Integer.toString(offset)), MusicDirectory.class); - if(dir == null) { - // If we are at start and no cache, throw error higher - if(offset == 0) { - throw e; - } else { - // Otherwise just pretend we are at the end of the list - return new MusicDirectory(); - } - } else { - return dir; - } - } - } + if(dir == null) { + // If we are at start and no cache, throw error higher + if(offset == 0) { + throw e; + } else { + // Otherwise just pretend we are at the end of the list + return new MusicDirectory(); + } + } else { + return dir; + } + } + } - @Override - public User getUser(boolean refresh, String username, Context context, ProgressListener progressListener) throws Exception { - User result = null; + @Override + public User getUser(boolean refresh, String username, Context context, ProgressListener progressListener) throws Exception { + User result = null; - try { - result = musicService.getUser(refresh, username, context, progressListener); - FileUtil.serialize(context, result, getCacheName(context, "user-" + username)); - } catch(Exception e) { - // Don't care - } - - if(result == null && !refresh) { - result = FileUtil.deserialize(context, getCacheName(context, "user-" + username), User.class); - } + try { + result = musicService.getUser(refresh, username, context, progressListener); + FileUtil.serialize(context, result, getCacheName(context, "user-" + username)); + } catch(Exception e) { + // Don't care + } - return result; - } + if(result == null && !refresh) { + result = FileUtil.deserialize(context, getCacheName(context, "user-" + username), User.class); + } - @Override - public Bitmap getBitmap(String url, int size, Context context, ProgressListener progressListener, SilentBackgroundTask task) throws Exception { - return musicService.getBitmap(url, size, context, progressListener, task); - } + return result; + } + + @Override + public Bitmap getBitmap(String url, int size, Context context, ProgressListener progressListener, SilentBackgroundTask task) throws Exception { + return musicService.getBitmap(url, size, context, progressListener, task); + } @Override - public void savePlayQueue(List songs, Entry currentPlaying, int position, Context context, ProgressListener progressListener) throws Exception { - musicService.savePlayQueue(songs, currentPlaying, position, context, progressListener); - } - - @Override - public PlayerQueue getPlayQueue(Context context, ProgressListener progressListener) throws Exception { - return musicService.getPlayQueue(context, progressListener); - } - - @Override - public void setInstance(Integer instance) throws Exception { - musicService.setInstance(instance); + public void savePlayQueue(List songs, Entry currentPlaying, int position, Context context, ProgressListener progressListener) throws Exception { + musicService.savePlayQueue(songs, currentPlaying, position, context, progressListener); } - - private String getCacheName(Context context, String name, String id) { - String s = musicService.getRestUrl(context, null, false) + id; - return name + "-" + s.hashCode() + ".ser"; - } - private String getCacheName(Context context, String name) { - String s = musicService.getRestUrl(context, null, false); - return name + "-" + s.hashCode() + ".ser"; - } - private void deleteRemovedEntries(Context context, MusicDirectory dir, MusicDirectory cached) { - if(cached != null) { - List oldList = new ArrayList(); - oldList.addAll(cached.getChildren()); + @Override + public PlayerQueue getPlayQueue(Context context, ProgressListener progressListener) throws Exception { + return musicService.getPlayQueue(context, progressListener); + } - // Remove all current items from old list - for(Entry entry: dir.getChildren()) { - oldList.remove(entry); - } + @Override + public void setInstance(Integer instance) throws Exception { + musicService.setInstance(instance); + } - // Anything remaining has been removed from server - MediaStoreService store = new MediaStoreService(context); - for(Entry entry: oldList) { - File file = FileUtil.getEntryFile(context, entry); - FileUtil.recursiveDelete(file, store); - } - } - } - - private abstract class SerializeUpdater { - final Context context; - final String cacheName; - final boolean singleUpdate; - - public SerializeUpdater(Context context, String cacheName) { - this(context, cacheName, true); - } - public SerializeUpdater(Context context, String cacheName, boolean singleUpdate) { - this.context = context; - this.cacheName = getCacheName(context, cacheName); - this.singleUpdate = singleUpdate; - } - public SerializeUpdater(Context context, String cacheName, String id) { - this(context, cacheName, id, true); - } - public SerializeUpdater(Context context, String cacheName, String id, boolean singleUpdate) { - this.context = context; - this.cacheName = getCacheName(context, cacheName, id); - this.singleUpdate = singleUpdate; - } + private String getCacheName(Context context, String name, String id) { + String s = musicService.getRestUrl(context, null, false) + id; + return name + "-" + s.hashCode() + ".ser"; + } + private String getCacheName(Context context, String name) { + String s = musicService.getRestUrl(context, null, false); + return name + "-" + s.hashCode() + ".ser"; + } - public ArrayList getArrayList() { - return FileUtil.deserialize(context, cacheName, ArrayList.class); - } - public abstract boolean checkResult(T check); - public abstract void updateResult(List objects, T result); - public void save(ArrayList objects) { - FileUtil.serialize(context, objects, cacheName); - } - - public void execute() { - ArrayList objects = getArrayList(); - - // Only execute if something to check against - if(objects != null) { - List results = new ArrayList(); - for(T check: objects) { - if(checkResult(check)) { - results.add(check); - if(singleUpdate) { - break; - } - } - } - - // Iterate through and update each object matched - for(T result: results) { - updateResult(objects, result); - } - - // Only reserialize if at least one match was found - if(results.size() > 0) { - save(objects); - } - } - } - } - private abstract class UserUpdater extends SerializeUpdater { - String username; - - public UserUpdater(Context context, String username) { - super(context, "users"); - this.username = username; - } - - @Override - public boolean checkResult(User check) { - return username.equals(check.getUsername()); - } - } - private abstract class PlaylistUpdater extends SerializeUpdater { - String id; + private void deleteRemovedEntries(Context context, MusicDirectory dir, MusicDirectory cached) { + if(cached != null) { + List oldList = new ArrayList(); + oldList.addAll(cached.getChildren()); - public PlaylistUpdater(Context context, String id) { - super(context, "playlist"); - this.id = id; - } + // Remove all current items from old list + for(Entry entry: dir.getChildren()) { + oldList.remove(entry); + } - @Override - public boolean checkResult(Playlist check) { - return id.equals(check.getId()); - } - } - private abstract class MusicDirectoryUpdater extends SerializeUpdater { - protected MusicDirectory musicDirectory; + // Anything remaining has been removed from server + MediaStoreService store = new MediaStoreService(context); + for(Entry entry: oldList) { + File file = FileUtil.getEntryFile(context, entry); + FileUtil.recursiveDelete(file, store); + } + } + } - public MusicDirectoryUpdater(Context context, String cacheName, String id) { - super(context, cacheName, id, true); - } - public MusicDirectoryUpdater(Context context, String cacheName, String id, boolean singleUpdate) { - super(context, cacheName, id, singleUpdate); - } + private abstract class SerializeUpdater { + final Context context; + final String cacheName; + final boolean singleUpdate; - @Override - public ArrayList getArrayList() { - musicDirectory = FileUtil.deserialize(context, cacheName, MusicDirectory.class); - if(musicDirectory != null) { - return new ArrayList<>(musicDirectory.getChildren()); - } else { - return null; - } - } - public void save(ArrayList objects) { - musicDirectory.replaceChildren(objects); - FileUtil.serialize(context, musicDirectory, cacheName); - } - } - private abstract class PlaylistDirectoryUpdater { - Context context; - - public PlaylistDirectoryUpdater(Context context) { - this.context = context; - } - - public abstract boolean checkResult(Entry check); - public abstract void updateResult(Entry result); - - public void execute() { - List playlists = FileUtil.deserialize(context, getCacheName(context, "playlist"), ArrayList.class); - if(playlists == null) { - // No playlist list cache, nothing to update! - return; - } - - for(Playlist playlist: playlists) { - new MusicDirectoryUpdater(context, "playlist", playlist.getId(), false) { - @Override - public boolean checkResult(Entry check) { - return PlaylistDirectoryUpdater.this.checkResult(check); - } - - @Override - public void updateResult(List objects, Entry result) { - PlaylistDirectoryUpdater.this.updateResult(result); - } - }.execute(); - } - } - } - private abstract class GenericEntryUpdater { - Context context; - List entries; - - public GenericEntryUpdater(Context context, Entry entry) { - this.context = context; - this.entries = Arrays.asList(entry); - } - public GenericEntryUpdater(Context context, List entries) { - this.context = context; - this.entries = entries; - } - - public boolean checkResult(Entry entry, Entry check) { - return entry.getId().equals(check.getId()); - } - public abstract void updateResult(Entry result); - - public void execute() { - String cacheName, parent; - // Make sure it is up to date - isTagBrowsing = Util.isTagBrowsing(context, musicService.getInstance(context)); - - // Run through each entry, trying to update the directory it is in - final List songs = new ArrayList(); - for(final Entry entry: entries) { - if(isTagBrowsing) { - // If starring album, needs to reference artist instead - if(entry.isDirectory()) { - if(entry.isAlbum()) { - cacheName = "artist"; - parent = entry.getArtistId(); - } else { - cacheName = "artists"; - parent = null; - } - } else { - cacheName = "album"; - parent = entry.getAlbumId(); - } - } else { - if(entry.isDirectory() && !entry.isAlbum()) { - cacheName = "indexes"; - parent = null; - } else { - cacheName = "directory"; - parent = entry.getParent(); - } - } + public SerializeUpdater(Context context, String cacheName) { + this(context, cacheName, true); + } + public SerializeUpdater(Context context, String cacheName, boolean singleUpdate) { + this.context = context; + this.cacheName = getCacheName(context, cacheName); + this.singleUpdate = singleUpdate; + } + public SerializeUpdater(Context context, String cacheName, String id) { + this(context, cacheName, id, true); + } + public SerializeUpdater(Context context, String cacheName, String id, boolean singleUpdate) { + this.context = context; + this.cacheName = getCacheName(context, cacheName, id); + this.singleUpdate = singleUpdate; + } + + public ArrayList getArrayList() { + return FileUtil.deserialize(context, cacheName, ArrayList.class); + } + public abstract boolean checkResult(T check); + public abstract void updateResult(List objects, T result); + public void save(ArrayList objects) { + FileUtil.serialize(context, objects, cacheName); + } + + public void execute() { + ArrayList objects = getArrayList(); + + // Only execute if something to check against + if(objects != null) { + List results = new ArrayList(); + for(T check: objects) { + if(checkResult(check)) { + results.add(check); + if(singleUpdate) { + break; + } + } + } + + // Iterate through and update each object matched + for(T result: results) { + updateResult(objects, result); + } + + // Only reserialize if at least one match was found + if(results.size() > 0) { + save(objects); + } + } + } + } + private abstract class UserUpdater extends SerializeUpdater { + String username; + + public UserUpdater(Context context, String username) { + super(context, "users"); + this.username = username; + } + + @Override + public boolean checkResult(User check) { + return username.equals(check.getUsername()); + } + } + private abstract class PlaylistUpdater extends SerializeUpdater { + String id; + + public PlaylistUpdater(Context context, String id) { + super(context, "playlist"); + this.id = id; + } + + @Override + public boolean checkResult(Playlist check) { + return id.equals(check.getId()); + } + } + private abstract class MusicDirectoryUpdater extends SerializeUpdater { + protected MusicDirectory musicDirectory; + + public MusicDirectoryUpdater(Context context, String cacheName, String id) { + super(context, cacheName, id, true); + } + public MusicDirectoryUpdater(Context context, String cacheName, String id, boolean singleUpdate) { + super(context, cacheName, id, singleUpdate); + } + + @Override + public ArrayList getArrayList() { + musicDirectory = FileUtil.deserialize(context, cacheName, MusicDirectory.class); + if(musicDirectory != null) { + return new ArrayList<>(musicDirectory.getChildren()); + } else { + return null; + } + } + public void save(ArrayList objects) { + musicDirectory.replaceChildren(objects); + FileUtil.serialize(context, musicDirectory, cacheName); + } + } + private abstract class PlaylistDirectoryUpdater { + Context context; + + public PlaylistDirectoryUpdater(Context context) { + this.context = context; + } + + public abstract boolean checkResult(Entry check); + public abstract void updateResult(Entry result); + + public void execute() { + List playlists = FileUtil.deserialize(context, getCacheName(context, "playlist"), ArrayList.class); + if(playlists == null) { + // No playlist list cache, nothing to update! + return; + } + + for(Playlist playlist: playlists) { + new MusicDirectoryUpdater(context, "playlist", playlist.getId(), false) { + @Override + public boolean checkResult(Entry check) { + return PlaylistDirectoryUpdater.this.checkResult(check); + } + + @Override + public void updateResult(List objects, Entry result) { + PlaylistDirectoryUpdater.this.updateResult(result); + } + }.execute(); + } + } + } + private abstract class GenericEntryUpdater { + Context context; + List entries; + + public GenericEntryUpdater(Context context, Entry entry) { + this.context = context; + this.entries = Arrays.asList(entry); + } + public GenericEntryUpdater(Context context, List entries) { + this.context = context; + this.entries = entries; + } + + public boolean checkResult(Entry entry, Entry check) { + return entry.getId().equals(check.getId()); + } + public abstract void updateResult(Entry result); + + public void execute() { + String cacheName, parent; + // Make sure it is up to date + isTagBrowsing = Util.isTagBrowsing(context, musicService.getInstance(context)); + + // Run through each entry, trying to update the directory it is in + final List songs = new ArrayList(); + for(final Entry entry: entries) { + if(isTagBrowsing) { + // If starring album, needs to reference artist instead + if(entry.isDirectory()) { + if(entry.isAlbum()) { + cacheName = "artist"; + parent = entry.getArtistId(); + } else { + cacheName = "artists"; + parent = null; + } + } else { + cacheName = "album"; + parent = entry.getAlbumId(); + } + } else { + if(entry.isDirectory() && !entry.isAlbum()) { + cacheName = "indexes"; + parent = null; + } else { + cacheName = "directory"; + parent = entry.getParent(); + } + } + + // Parent is only null when it is an artist + if(parent == null) { + new IndexesUpdater(context, cacheName) { + @Override + public boolean checkResult(Artist check) { + return GenericEntryUpdater.this.checkResult(entry, new Entry(check)); + } + + @Override + public void updateResult(List objects, Artist result) { + // Don't try to put anything here, as the Entry update method will not be called since it's a artist! + } + }.execute(); + } else { + new MusicDirectoryUpdater(context, cacheName, parent) { + @Override + public boolean checkResult(Entry check) { + return GenericEntryUpdater.this.checkResult(entry, check); + } + + @Override + public void updateResult(List objects, Entry result) { + GenericEntryUpdater.this.updateResult(result); + } + }.execute(); + } - // Parent is only null when it is an artist - if(parent == null) { - new IndexesUpdater(context, cacheName) { - @Override - public boolean checkResult(Artist check) { - return GenericEntryUpdater.this.checkResult(entry, new Entry(check)); - } - - @Override - public void updateResult(List objects, Artist result) { - // Don't try to put anything here, as the Entry update method will not be called since it's a artist! - } - }.execute(); - } else { - new MusicDirectoryUpdater(context, cacheName, parent) { - @Override - public boolean checkResult(Entry check) { - return GenericEntryUpdater.this.checkResult(entry, check); - } - - @Override - public void updateResult(List objects, Entry result) { - GenericEntryUpdater.this.updateResult(result); - } - }.execute(); - } - songs.add(entry); - } - - // Only run through playlists once and check each song against it - if(songs.size() > 0) { - new PlaylistDirectoryUpdater(context) { - @Override - public boolean checkResult(Entry check) { - for(Entry entry: songs) { - if(GenericEntryUpdater.this.checkResult(entry, check)) { - return true; - } - } - - return false; - } - - @Override - public void updateResult(Entry result) { - GenericEntryUpdater.this.updateResult(result); - } - }.execute(); - } - } - } + } - private class StarUpdater extends GenericEntryUpdater { - public StarUpdater(Context context, List entries) { - super(context, entries); - } + // Only run through playlists once and check each song against it + if(songs.size() > 0) { + new PlaylistDirectoryUpdater(context) { + @Override + public boolean checkResult(Entry check) { + for(Entry entry: songs) { + if(GenericEntryUpdater.this.checkResult(entry, check)) { + return true; + } + } - @Override - public boolean checkResult(Entry entry, Entry check) { - if (!entry.getId().equals(check.getId())) { - return false; - } + return false; + } - return true; - } + @Override + public void updateResult(Entry result) { + GenericEntryUpdater.this.updateResult(result); + } + }.execute(); + } + } + } - @Override - public void updateResult(Entry result) { + private class StarUpdater extends GenericEntryUpdater { + public StarUpdater(Context context, List entries) { + super(context, entries); + } - } - }; - private abstract class IndexesUpdater extends SerializeUpdater { - Indexes indexes; + @Override + public boolean checkResult(Entry entry, Entry check) { + if (!entry.getId().equals(check.getId())) { + return false; + } - IndexesUpdater(Context context, String name) { - super(context, name, Util.getSelectedMusicFolderId(context, musicService.getInstance(context))); - } + return true; + } - @Override - public ArrayList getArrayList() { - indexes = FileUtil.deserialize(context, cacheName, Indexes.class); - if(indexes == null) { - return null; - } + @Override + public void updateResult(Entry result) { - ArrayList artists = new ArrayList(); - artists.addAll(indexes.getArtists()); - artists.addAll(indexes.getShortcuts()); - return artists; - } + } + }; + private abstract class IndexesUpdater extends SerializeUpdater { + Indexes indexes; - public void save(ArrayList objects) { - indexes.setArtists(objects); - FileUtil.serialize(context, indexes, cacheName); - cachedIndexes.set(indexes); - } - } + IndexesUpdater(Context context, String name) { + super(context, name, Util.getSelectedMusicFolderId(context, musicService.getInstance(context))); + } - protected void updateAllSongs(Context context, MusicDirectory dir) { - List songs = dir.getSongs(); - if(!songs.isEmpty()) { - SongDBHandler.getHandler(context).addSongs(musicService.getInstance(context), songs); - } - } + @Override + public ArrayList getArrayList() { + indexes = FileUtil.deserialize(context, cacheName, Indexes.class); + if(indexes == null) { + return null; + } + + ArrayList artists = new ArrayList(); + artists.addAll(indexes.getArtists()); + artists.addAll(indexes.getShortcuts()); + return artists; + } + + public void save(ArrayList objects) { + indexes.setArtists(objects); + FileUtil.serialize(context, indexes, cacheName); + cachedIndexes.set(indexes); + } + } + + protected void updateAllSongs(Context context, MusicDirectory dir) { + List songs = dir.getSongs(); + if(!songs.isEmpty()) { + SongDBHandler.getHandler(context).addSongs(musicService.getInstance(context), songs); + } + } private void checkSettingsChanged(Context context) { - int instance = musicService.getInstance(context); + int instance = musicService.getInstance(context); String newUrl = musicService.getRestUrl(context, null, false); - boolean newIsTagBrowsing = Util.isTagBrowsing(context, instance); + boolean newIsTagBrowsing = Util.isTagBrowsing(context, instance); if (!Util.equals(newUrl, restUrl) || isTagBrowsing != newIsTagBrowsing) { cachedMusicFolders.clear(); cachedIndexes.clear(); cachedPlaylists.clear(); restUrl = newUrl; - isTagBrowsing = newIsTagBrowsing; + isTagBrowsing = newIsTagBrowsing; } - String newMusicFolderId = Util.getSelectedMusicFolderId(context, instance); - if(!Util.equals(newMusicFolderId, musicFolderId)) { - cachedIndexes.clear(); - musicFolderId = newMusicFolderId; - } + String newMusicFolderId = Util.getSelectedMusicFolderId(context, instance); + if(!Util.equals(newMusicFolderId, musicFolderId)) { + cachedIndexes.clear(); + musicFolderId = newMusicFolderId; + } } - public RESTMusicService getMusicService() { - return musicService; - } + public RESTMusicService getMusicService() { + return musicService; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/service/DownloadServiceLifecycleSupport.java b/app/src/main/java/net/nullsum/audinaut/service/DownloadServiceLifecycleSupport.java index 6c6e35b..caa05a6 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/DownloadServiceLifecycleSupport.java +++ b/app/src/main/java/net/nullsum/audinaut/service/DownloadServiceLifecycleSupport.java @@ -53,378 +53,378 @@ import static net.nullsum.audinaut.domain.PlayerState.PREPARING; * @author Sindre Mehus */ public class DownloadServiceLifecycleSupport { - private static final String TAG = DownloadServiceLifecycleSupport.class.getSimpleName(); - public static final String FILENAME_DOWNLOADS_SER = "downloadstate2.ser"; - private static final int DEBOUNCE_TIME = 200; + private static final String TAG = DownloadServiceLifecycleSupport.class.getSimpleName(); + public static final String FILENAME_DOWNLOADS_SER = "downloadstate2.ser"; + private static final int DEBOUNCE_TIME = 200; - private final DownloadService downloadService; - private Looper eventLooper; - private Handler eventHandler; - private BroadcastReceiver ejectEventReceiver; - private PhoneStateListener phoneStateListener; - private boolean externalStorageAvailable= true; - private ReentrantLock lock = new ReentrantLock(); - private final AtomicBoolean setup = new AtomicBoolean(false); - private long lastPressTime = 0; - private SilentBackgroundTask currentSavePlayQueueTask = null; - private Date lastChange = null; + private final DownloadService downloadService; + private Looper eventLooper; + private Handler eventHandler; + private BroadcastReceiver ejectEventReceiver; + private PhoneStateListener phoneStateListener; + private boolean externalStorageAvailable= true; + private ReentrantLock lock = new ReentrantLock(); + private final AtomicBoolean setup = new AtomicBoolean(false); + private long lastPressTime = 0; + private SilentBackgroundTask currentSavePlayQueueTask = null; + private Date lastChange = null; - /** - * This receiver manages the intent that could come from other applications. - */ - private BroadcastReceiver intentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(final Context context, final Intent intent) { - eventHandler.post(new Runnable() { - @Override - public void run() { - String action = intent.getAction(); - Log.i(TAG, "intentReceiver.onReceive: " + action); - if (DownloadService.CMD_PLAY.equals(action)) { - downloadService.play(); - } else if (DownloadService.CMD_NEXT.equals(action)) { - downloadService.next(); - } else if (DownloadService.CMD_PREVIOUS.equals(action)) { - downloadService.previous(); - } else if (DownloadService.CMD_TOGGLEPAUSE.equals(action)) { - downloadService.togglePlayPause(); - } else if (DownloadService.CMD_PAUSE.equals(action)) { - downloadService.pause(); - } else if (DownloadService.CMD_STOP.equals(action)) { - downloadService.pause(); - downloadService.seekTo(0); - } - } - }); - } - }; + /** + * This receiver manages the intent that could come from other applications. + */ + private BroadcastReceiver intentReceiver = new BroadcastReceiver() { + @Override + public void onReceive(final Context context, final Intent intent) { + eventHandler.post(new Runnable() { + @Override + public void run() { + String action = intent.getAction(); + Log.i(TAG, "intentReceiver.onReceive: " + action); + if (DownloadService.CMD_PLAY.equals(action)) { + downloadService.play(); + } else if (DownloadService.CMD_NEXT.equals(action)) { + downloadService.next(); + } else if (DownloadService.CMD_PREVIOUS.equals(action)) { + downloadService.previous(); + } else if (DownloadService.CMD_TOGGLEPAUSE.equals(action)) { + downloadService.togglePlayPause(); + } else if (DownloadService.CMD_PAUSE.equals(action)) { + downloadService.pause(); + } else if (DownloadService.CMD_STOP.equals(action)) { + downloadService.pause(); + downloadService.seekTo(0); + } + } + }); + } + }; - public DownloadServiceLifecycleSupport(DownloadService downloadService) { - this.downloadService = downloadService; - } + public DownloadServiceLifecycleSupport(DownloadService downloadService) { + this.downloadService = downloadService; + } - public void onCreate() { - new Thread(new Runnable() { - @Override - public void run() { - Looper.prepare(); - eventLooper = Looper.myLooper(); - eventHandler = new Handler(eventLooper); + public void onCreate() { + new Thread(new Runnable() { + @Override + public void run() { + Looper.prepare(); + eventLooper = Looper.myLooper(); + eventHandler = new Handler(eventLooper); - // Deserialize queue before starting looper - try { - lock.lock(); - deserializeDownloadQueueNow(); + // Deserialize queue before starting looper + try { + lock.lock(); + deserializeDownloadQueueNow(); - // Wait until PREPARING is done to mark lifecycle as ready to receive events - while(downloadService.getPlayerState() == PREPARING) { - Util.sleepQuietly(50L); - } + // Wait until PREPARING is done to mark lifecycle as ready to receive events + while(downloadService.getPlayerState() == PREPARING) { + Util.sleepQuietly(50L); + } - setup.set(true); - } finally { - lock.unlock(); - } + setup.set(true); + } finally { + lock.unlock(); + } - Looper.loop(); - } - }, "DownloadServiceLifecycleSupport").start(); + Looper.loop(); + } + }, "DownloadServiceLifecycleSupport").start(); - // Stop when SD card is ejected. - ejectEventReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - externalStorageAvailable = Intent.ACTION_MEDIA_MOUNTED.equals(intent.getAction()); - if (!externalStorageAvailable) { - Log.i(TAG, "External media is ejecting. Stopping playback."); - downloadService.reset(); - } else { - Log.i(TAG, "External media is available."); - } - } - }; - IntentFilter ejectFilter = new IntentFilter(Intent.ACTION_MEDIA_EJECT); - ejectFilter.addAction(Intent.ACTION_MEDIA_MOUNTED); - ejectFilter.addDataScheme("file"); - downloadService.registerReceiver(ejectEventReceiver, ejectFilter); + // Stop when SD card is ejected. + ejectEventReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + externalStorageAvailable = Intent.ACTION_MEDIA_MOUNTED.equals(intent.getAction()); + if (!externalStorageAvailable) { + Log.i(TAG, "External media is ejecting. Stopping playback."); + downloadService.reset(); + } else { + Log.i(TAG, "External media is available."); + } + } + }; + IntentFilter ejectFilter = new IntentFilter(Intent.ACTION_MEDIA_EJECT); + ejectFilter.addAction(Intent.ACTION_MEDIA_MOUNTED); + ejectFilter.addDataScheme("file"); + downloadService.registerReceiver(ejectEventReceiver, ejectFilter); - // React to media buttons. - Util.registerMediaButtonEventReceiver(downloadService); + // React to media buttons. + Util.registerMediaButtonEventReceiver(downloadService); - // Pause temporarily on incoming phone calls. - phoneStateListener = new MyPhoneStateListener(); + // Pause temporarily on incoming phone calls. + phoneStateListener = new MyPhoneStateListener(); - // Android 6.0 removes requirement for android.Manifest.permission.READ_PHONE_STATE; - TelephonyManager telephonyManager = (TelephonyManager) downloadService.getSystemService(Context.TELEPHONY_SERVICE); - telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); + // Android 6.0 removes requirement for android.Manifest.permission.READ_PHONE_STATE; + TelephonyManager telephonyManager = (TelephonyManager) downloadService.getSystemService(Context.TELEPHONY_SERVICE); + telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); - // Register the handler for outside intents. - IntentFilter commandFilter = new IntentFilter(); - commandFilter.addAction(DownloadService.CMD_PLAY); - commandFilter.addAction(DownloadService.CMD_TOGGLEPAUSE); - commandFilter.addAction(DownloadService.CMD_PAUSE); - commandFilter.addAction(DownloadService.CMD_STOP); - commandFilter.addAction(DownloadService.CMD_PREVIOUS); - commandFilter.addAction(DownloadService.CMD_NEXT); - commandFilter.addAction(DownloadService.CANCEL_DOWNLOADS); - downloadService.registerReceiver(intentReceiver, commandFilter); + // Register the handler for outside intents. + IntentFilter commandFilter = new IntentFilter(); + commandFilter.addAction(DownloadService.CMD_PLAY); + commandFilter.addAction(DownloadService.CMD_TOGGLEPAUSE); + commandFilter.addAction(DownloadService.CMD_PAUSE); + commandFilter.addAction(DownloadService.CMD_STOP); + commandFilter.addAction(DownloadService.CMD_PREVIOUS); + commandFilter.addAction(DownloadService.CMD_NEXT); + commandFilter.addAction(DownloadService.CANCEL_DOWNLOADS); + downloadService.registerReceiver(intentReceiver, commandFilter); - new CacheCleaner(downloadService, downloadService).clean(); - } + new CacheCleaner(downloadService, downloadService).clean(); + } - public boolean isInitialized() { - return setup.get(); - } + public boolean isInitialized() { + return setup.get(); + } - public void onStart(final Intent intent) { - if (intent != null) { - final String action = intent.getAction(); + public void onStart(final Intent intent) { + if (intent != null) { + final String action = intent.getAction(); - if(eventHandler == null) { - Util.sleepQuietly(100L); - } - if(eventHandler == null) { - return; - } + if(eventHandler == null) { + Util.sleepQuietly(100L); + } + if(eventHandler == null) { + return; + } - eventHandler.post(new Runnable() { - @Override - public void run() { - if(!setup.get()) { - lock.lock(); - lock.unlock(); - } + eventHandler.post(new Runnable() { + @Override + public void run() { + if(!setup.get()) { + lock.lock(); + lock.unlock(); + } - if(DownloadService.START_PLAY.equals(action)) { - int offlinePref = intent.getIntExtra(Constants.PREFERENCES_KEY_OFFLINE, 0); - if(offlinePref != 0) { - boolean offline = (offlinePref == 2); - Util.setOffline(downloadService, offline); - if (offline) { - downloadService.clearIncomplete(); - } else { - downloadService.checkDownloads(); - } - } + if(DownloadService.START_PLAY.equals(action)) { + int offlinePref = intent.getIntExtra(Constants.PREFERENCES_KEY_OFFLINE, 0); + if(offlinePref != 0) { + boolean offline = (offlinePref == 2); + Util.setOffline(downloadService, offline); + if (offline) { + downloadService.clearIncomplete(); + } else { + downloadService.checkDownloads(); + } + } - if(intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_SHUFFLE, false)) { - // Add shuffle parameters - SharedPreferences.Editor editor = Util.getPreferences(downloadService).edit(); - String startYear = intent.getStringExtra(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR); - if(startYear != null) { - editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, startYear); - } + if(intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_SHUFFLE, false)) { + // Add shuffle parameters + SharedPreferences.Editor editor = Util.getPreferences(downloadService).edit(); + String startYear = intent.getStringExtra(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR); + if(startYear != null) { + editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, startYear); + } - String endYear = intent.getStringExtra(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR); - if(endYear != null) { - editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, endYear); - } + String endYear = intent.getStringExtra(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR); + if(endYear != null) { + editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, endYear); + } - String genre = intent.getStringExtra(Constants.PREFERENCES_KEY_SHUFFLE_GENRE); - if(genre != null) { - editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, genre); - } - editor.apply(); + String genre = intent.getStringExtra(Constants.PREFERENCES_KEY_SHUFFLE_GENRE); + if(genre != null) { + editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, genre); + } + editor.apply(); - downloadService.clear(); - downloadService.setShufflePlayEnabled(true); - } else { - downloadService.start(); - } - } else if(DownloadService.CMD_TOGGLEPAUSE.equals(action)) { - downloadService.togglePlayPause(); - } else if(DownloadService.CMD_NEXT.equals(action)) { - downloadService.next(); - } else if(DownloadService.CMD_PREVIOUS.equals(action)) { - downloadService.previous(); - } else if(DownloadService.CANCEL_DOWNLOADS.equals(action)) { - downloadService.clearBackground(); - } else if(intent.getExtras() != null) { - final KeyEvent event = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT); - if (event != null) { - handleKeyEvent(event); - } - } - } - }); - } - } + downloadService.clear(); + downloadService.setShufflePlayEnabled(true); + } else { + downloadService.start(); + } + } else if(DownloadService.CMD_TOGGLEPAUSE.equals(action)) { + downloadService.togglePlayPause(); + } else if(DownloadService.CMD_NEXT.equals(action)) { + downloadService.next(); + } else if(DownloadService.CMD_PREVIOUS.equals(action)) { + downloadService.previous(); + } else if(DownloadService.CANCEL_DOWNLOADS.equals(action)) { + downloadService.clearBackground(); + } else if(intent.getExtras() != null) { + final KeyEvent event = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT); + if (event != null) { + handleKeyEvent(event); + } + } + } + }); + } + } - public void onDestroy() { - serializeDownloadQueue(); - eventLooper.quit(); - downloadService.unregisterReceiver(ejectEventReceiver); - downloadService.unregisterReceiver(intentReceiver); + public void onDestroy() { + serializeDownloadQueue(); + eventLooper.quit(); + downloadService.unregisterReceiver(ejectEventReceiver); + downloadService.unregisterReceiver(intentReceiver); - TelephonyManager telephonyManager = (TelephonyManager) downloadService.getSystemService(Context.TELEPHONY_SERVICE); - telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE); - } + TelephonyManager telephonyManager = (TelephonyManager) downloadService.getSystemService(Context.TELEPHONY_SERVICE); + telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE); + } - public boolean isExternalStorageAvailable() { - return externalStorageAvailable; - } + public boolean isExternalStorageAvailable() { + return externalStorageAvailable; + } - public void serializeDownloadQueue() { - serializeDownloadQueue(true); - } - public void serializeDownloadQueue(final boolean serializeRemote) { - if(!setup.get()) { - return; - } + public void serializeDownloadQueue() { + serializeDownloadQueue(true); + } + public void serializeDownloadQueue(final boolean serializeRemote) { + if(!setup.get()) { + return; + } - final List songs = new ArrayList(downloadService.getSongs()); - eventHandler.post(new Runnable() { - @Override - public void run() { - if(lock.tryLock()) { - try { - serializeDownloadQueueNow(songs, serializeRemote); - } finally { - lock.unlock(); - } - } - } - }); - } + final List songs = new ArrayList(downloadService.getSongs()); + eventHandler.post(new Runnable() { + @Override + public void run() { + if(lock.tryLock()) { + try { + serializeDownloadQueueNow(songs, serializeRemote); + } finally { + lock.unlock(); + } + } + } + }); + } - public void serializeDownloadQueueNow(List songs, boolean serializeRemote) { - final PlayerQueue state = new PlayerQueue(); - for (DownloadFile downloadFile : songs) { - state.songs.add(downloadFile.getSong()); - } - for (DownloadFile downloadFile : downloadService.getToDelete()) { - state.toDelete.add(downloadFile.getSong()); - } - state.currentPlayingIndex = downloadService.getCurrentPlayingIndex(); - state.currentPlayingPosition = downloadService.getPlayerPosition(); + public void serializeDownloadQueueNow(List songs, boolean serializeRemote) { + final PlayerQueue state = new PlayerQueue(); + for (DownloadFile downloadFile : songs) { + state.songs.add(downloadFile.getSong()); + } + for (DownloadFile downloadFile : downloadService.getToDelete()) { + state.toDelete.add(downloadFile.getSong()); + } + state.currentPlayingIndex = downloadService.getCurrentPlayingIndex(); + state.currentPlayingPosition = downloadService.getPlayerPosition(); - DownloadFile currentPlaying = downloadService.getCurrentPlaying(); - if(currentPlaying != null) { - state.renameCurrent = currentPlaying.isWorkDone() && !currentPlaying.isCompleteFileAvailable(); - } - state.changed = lastChange = new Date(); + DownloadFile currentPlaying = downloadService.getCurrentPlaying(); + if(currentPlaying != null) { + state.renameCurrent = currentPlaying.isWorkDone() && !currentPlaying.isCompleteFileAvailable(); + } + state.changed = lastChange = new Date(); - Log.i(TAG, "Serialized currentPlayingIndex: " + state.currentPlayingIndex + ", currentPlayingPosition: " + state.currentPlayingPosition); - FileUtil.serialize(downloadService, state, FILENAME_DOWNLOADS_SER); - } + Log.i(TAG, "Serialized currentPlayingIndex: " + state.currentPlayingIndex + ", currentPlayingPosition: " + state.currentPlayingPosition); + FileUtil.serialize(downloadService, state, FILENAME_DOWNLOADS_SER); + } - public void post(Runnable runnable) { - eventHandler.post(runnable); - } + public void post(Runnable runnable) { + eventHandler.post(runnable); + } - private void deserializeDownloadQueueNow() { - PlayerQueue state = FileUtil.deserialize(downloadService, FILENAME_DOWNLOADS_SER, PlayerQueue.class); - if (state == null) { - return; - } - Log.i(TAG, "Deserialized currentPlayingIndex: " + state.currentPlayingIndex + ", currentPlayingPosition: " + state.currentPlayingPosition); + private void deserializeDownloadQueueNow() { + PlayerQueue state = FileUtil.deserialize(downloadService, FILENAME_DOWNLOADS_SER, PlayerQueue.class); + if (state == null) { + return; + } + Log.i(TAG, "Deserialized currentPlayingIndex: " + state.currentPlayingIndex + ", currentPlayingPosition: " + state.currentPlayingPosition); - // Rename first thing before anything else starts - if(state.renameCurrent && state.currentPlayingIndex != -1 && state.currentPlayingIndex < state.songs.size()) { - DownloadFile currentPlaying = new DownloadFile(downloadService, state.songs.get(state.currentPlayingIndex), false); - currentPlaying.renamePartial(); - } + // Rename first thing before anything else starts + if(state.renameCurrent && state.currentPlayingIndex != -1 && state.currentPlayingIndex < state.songs.size()) { + DownloadFile currentPlaying = new DownloadFile(downloadService, state.songs.get(state.currentPlayingIndex), false); + currentPlaying.renamePartial(); + } - downloadService.restore(state.songs, state.toDelete, state.currentPlayingIndex, state.currentPlayingPosition); + downloadService.restore(state.songs, state.toDelete, state.currentPlayingIndex, state.currentPlayingPosition); - if(state != null) { - lastChange = state.changed; - } - } + if(state != null) { + lastChange = state.changed; + } + } - public Date getLastChange() { - return lastChange; - } + public Date getLastChange() { + return lastChange; + } - public void handleKeyEvent(KeyEvent event) { - if(event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() > 0) { - switch (event.getKeyCode()) { - case KeyEvent.KEYCODE_MEDIA_PREVIOUS: - downloadService.fastForward(); - break; - case KeyEvent.KEYCODE_MEDIA_NEXT: - downloadService.rewind(); - break; - } - } else if(event.getAction() == KeyEvent.ACTION_UP) { - switch (event.getKeyCode()) { - case KeyEvent.KEYCODE_HEADSETHOOK: - case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: - if(lastPressTime < (System.currentTimeMillis() - 500)) { - lastPressTime = System.currentTimeMillis(); - downloadService.togglePlayPause(); - } else { - downloadService.next(false, true); - } - break; - case KeyEvent.KEYCODE_MEDIA_PREVIOUS: - if(lastPressTime < (System.currentTimeMillis() - DEBOUNCE_TIME)) { - lastPressTime = System.currentTimeMillis(); - downloadService.previous(); - } - break; - case KeyEvent.KEYCODE_MEDIA_NEXT: - if(lastPressTime < (System.currentTimeMillis() - DEBOUNCE_TIME)) { - lastPressTime = System.currentTimeMillis(); - downloadService.next(); - } - break; - case KeyEvent.KEYCODE_MEDIA_REWIND: - downloadService.rewind(); - break; - case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: - downloadService.fastForward(); - break; - case KeyEvent.KEYCODE_MEDIA_STOP: - downloadService.stop(); - break; - case KeyEvent.KEYCODE_MEDIA_PLAY: - if(downloadService.getPlayerState() != PlayerState.STARTED) { - downloadService.start(); - } - break; - case KeyEvent.KEYCODE_MEDIA_PAUSE: - downloadService.pause(); - default: - break; - } - } - } + public void handleKeyEvent(KeyEvent event) { + if(event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() > 0) { + switch (event.getKeyCode()) { + case KeyEvent.KEYCODE_MEDIA_PREVIOUS: + downloadService.fastForward(); + break; + case KeyEvent.KEYCODE_MEDIA_NEXT: + downloadService.rewind(); + break; + } + } else if(event.getAction() == KeyEvent.ACTION_UP) { + switch (event.getKeyCode()) { + case KeyEvent.KEYCODE_HEADSETHOOK: + case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE: + if(lastPressTime < (System.currentTimeMillis() - 500)) { + lastPressTime = System.currentTimeMillis(); + downloadService.togglePlayPause(); + } else { + downloadService.next(false, true); + } + break; + case KeyEvent.KEYCODE_MEDIA_PREVIOUS: + if(lastPressTime < (System.currentTimeMillis() - DEBOUNCE_TIME)) { + lastPressTime = System.currentTimeMillis(); + downloadService.previous(); + } + break; + case KeyEvent.KEYCODE_MEDIA_NEXT: + if(lastPressTime < (System.currentTimeMillis() - DEBOUNCE_TIME)) { + lastPressTime = System.currentTimeMillis(); + downloadService.next(); + } + break; + case KeyEvent.KEYCODE_MEDIA_REWIND: + downloadService.rewind(); + break; + case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD: + downloadService.fastForward(); + break; + case KeyEvent.KEYCODE_MEDIA_STOP: + downloadService.stop(); + break; + case KeyEvent.KEYCODE_MEDIA_PLAY: + if(downloadService.getPlayerState() != PlayerState.STARTED) { + downloadService.start(); + } + break; + case KeyEvent.KEYCODE_MEDIA_PAUSE: + downloadService.pause(); + default: + break; + } + } + } - /** - * Logic taken from packages/apps/Music. Will pause when an incoming - * call rings or if a call (incoming or outgoing) is connected. - */ - private class MyPhoneStateListener extends PhoneStateListener { - private boolean resumeAfterCall; + /** + * Logic taken from packages/apps/Music. Will pause when an incoming + * call rings or if a call (incoming or outgoing) is connected. + */ + private class MyPhoneStateListener extends PhoneStateListener { + private boolean resumeAfterCall; - @Override - public void onCallStateChanged(final int state, String incomingNumber) { - eventHandler.post(new Runnable() { - @Override - public void run() { - switch (state) { - case TelephonyManager.CALL_STATE_RINGING: - case TelephonyManager.CALL_STATE_OFFHOOK: - if (downloadService.getPlayerState() == PlayerState.STARTED) { - resumeAfterCall = true; - downloadService.pause(true); - } - break; - case TelephonyManager.CALL_STATE_IDLE: - if (resumeAfterCall) { - resumeAfterCall = false; - if(downloadService.getPlayerState() == PlayerState.PAUSED_TEMP) { - downloadService.start(); - } - } - break; - default: - break; - } - } - }); - } - } + @Override + public void onCallStateChanged(final int state, String incomingNumber) { + eventHandler.post(new Runnable() { + @Override + public void run() { + switch (state) { + case TelephonyManager.CALL_STATE_RINGING: + case TelephonyManager.CALL_STATE_OFFHOOK: + if (downloadService.getPlayerState() == PlayerState.STARTED) { + resumeAfterCall = true; + downloadService.pause(true); + } + break; + case TelephonyManager.CALL_STATE_IDLE: + if (resumeAfterCall) { + resumeAfterCall = false; + if(downloadService.getPlayerState() == PlayerState.PAUSED_TEMP) { + downloadService.start(); + } + } + break; + default: + break; + } + } + }); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/service/HeadphoneListenerService.java b/app/src/main/java/net/nullsum/audinaut/service/HeadphoneListenerService.java index 15ea24e..2fb9aca 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/HeadphoneListenerService.java +++ b/app/src/main/java/net/nullsum/audinaut/service/HeadphoneListenerService.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.service; @@ -27,40 +27,40 @@ import net.nullsum.audinaut.util.Util; * Created by Scott on 4/6/2015. */ public class HeadphoneListenerService extends Service { - private HeadphonePlugReceiver receiver; + private HeadphonePlugReceiver receiver; - @Override - public void onCreate() { - super.onCreate(); + @Override + public void onCreate() { + super.onCreate(); - receiver = new HeadphonePlugReceiver(); - registerReceiver(receiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG)); - } + receiver = new HeadphonePlugReceiver(); + registerReceiver(receiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG)); + } - @Override - public IBinder onBind(Intent intent) { - return null; - } + @Override + public IBinder onBind(Intent intent) { + return null; + } - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if(!Util.shouldStartOnHeadphones(this)) { - stopSelf(); - } + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + if(!Util.shouldStartOnHeadphones(this)) { + stopSelf(); + } - return Service.START_STICKY; - } + return Service.START_STICKY; + } - @Override - public void onDestroy() { - super.onDestroy(); + @Override + public void onDestroy() { + super.onDestroy(); - try { - if(receiver != null) { - unregisterReceiver(receiver); - } - } catch(Exception e) { - // Don't care - } - } + try { + if(receiver != null) { + unregisterReceiver(receiver); + } + } catch(Exception e) { + // Don't care + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/service/MediaStoreService.java b/app/src/main/java/net/nullsum/audinaut/service/MediaStoreService.java index 8c9e3a8..39e2dc6 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/MediaStoreService.java +++ b/app/src/main/java/net/nullsum/audinaut/service/MediaStoreService.java @@ -36,24 +36,24 @@ import net.nullsum.audinaut.util.Util; */ public class MediaStoreService { - private static final String TAG = MediaStoreService.class.getSimpleName(); - private static final Uri ALBUM_ART_URI = Uri.parse("content://media/external/audio/albumart"); + private static final String TAG = MediaStoreService.class.getSimpleName(); + private static final Uri ALBUM_ART_URI = Uri.parse("content://media/external/audio/albumart"); - private final Context context; + private final Context context; - public MediaStoreService(Context context) { - this.context = context; - } + public MediaStoreService(Context context) { + this.context = context; + } - public void saveInMediaStore(DownloadFile downloadFile) { - MusicDirectory.Entry song = downloadFile.getSong(); - File songFile = downloadFile.getCompleteFile(); + public void saveInMediaStore(DownloadFile downloadFile) { + MusicDirectory.Entry song = downloadFile.getSong(); + File songFile = downloadFile.getCompleteFile(); - // Delete existing row in case the song has been downloaded before. - deleteFromMediaStore(downloadFile); + // Delete existing row in case the song has been downloaded before. + deleteFromMediaStore(downloadFile); - ContentResolver contentResolver = context.getContentResolver(); - ContentValues values = new ContentValues(); + ContentResolver contentResolver = context.getContentResolver(); + ContentValues values = new ContentValues(); values.put(MediaStore.MediaColumns.TITLE, song.getTitle()); values.put(MediaStore.MediaColumns.DATA, songFile.getAbsolutePath()); values.put(MediaStore.Audio.AudioColumns.ARTIST, song.getArtist()); @@ -84,68 +84,68 @@ public class MediaStoreService { } cursor.close(); - } + } - public void deleteFromMediaStore(DownloadFile downloadFile) { - ContentResolver contentResolver = context.getContentResolver(); - MusicDirectory.Entry song = downloadFile.getSong(); - File file = downloadFile.getCompleteFile(); + public void deleteFromMediaStore(DownloadFile downloadFile) { + ContentResolver contentResolver = context.getContentResolver(); + MusicDirectory.Entry song = downloadFile.getSong(); + File file = downloadFile.getCompleteFile(); Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; - int n = contentResolver.delete(uri, - MediaStore.MediaColumns.DATA + "=?", - new String[]{file.getAbsolutePath()}); - if (n > 0) { - Log.i(TAG, "Deleting media store row for " + song); - } - } + int n = contentResolver.delete(uri, + MediaStore.MediaColumns.DATA + "=?", + new String[]{file.getAbsolutePath()}); + if (n > 0) { + Log.i(TAG, "Deleting media store row for " + song); + } + } - public void deleteFromMediaStore(File file) { - ContentResolver contentResolver = context.getContentResolver(); + public void deleteFromMediaStore(File file) { + ContentResolver contentResolver = context.getContentResolver(); - Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; - int n = contentResolver.delete(uri, - MediaStore.MediaColumns.DATA + "=?", - new String[]{file.getAbsolutePath()}); - if (n > 0) { - Log.i(TAG, "Deleting media store row for " + file); - } - } + int n = contentResolver.delete(uri, + MediaStore.MediaColumns.DATA + "=?", + new String[]{file.getAbsolutePath()}); + if (n > 0) { + Log.i(TAG, "Deleting media store row for " + file); + } + } - public void renameInMediaStore(File start, File end) { - ContentResolver contentResolver = context.getContentResolver(); + public void renameInMediaStore(File start, File end) { + ContentResolver contentResolver = context.getContentResolver(); - ContentValues values = new ContentValues(); - values.put(MediaStore.MediaColumns.DATA, end.getAbsolutePath()); + ContentValues values = new ContentValues(); + values.put(MediaStore.MediaColumns.DATA, end.getAbsolutePath()); - int n = contentResolver.update(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, - values, - MediaStore.MediaColumns.DATA + "=?", - new String[]{start.getAbsolutePath()}); - if (n > 0) { - Log.i(TAG, "Rename media store row for " + start + " to " + end); - } - } + int n = contentResolver.update(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, + values, + MediaStore.MediaColumns.DATA + "=?", + new String[]{start.getAbsolutePath()}); + if (n > 0) { + Log.i(TAG, "Rename media store row for " + start + " to " + end); + } + } - private void insertAlbumArt(int albumId, DownloadFile downloadFile) { - ContentResolver contentResolver = context.getContentResolver(); + private void insertAlbumArt(int albumId, DownloadFile downloadFile) { + ContentResolver contentResolver = context.getContentResolver(); - Cursor cursor = contentResolver.query(Uri.withAppendedPath(ALBUM_ART_URI, String.valueOf(albumId)), null, null, null, null); - if (!cursor.moveToFirst()) { + Cursor cursor = contentResolver.query(Uri.withAppendedPath(ALBUM_ART_URI, String.valueOf(albumId)), null, null, null, null); + if (!cursor.moveToFirst()) { - // No album art found, add it. - File albumArtFile = FileUtil.getAlbumArtFile(context, downloadFile.getSong()); - if (albumArtFile.exists()) { - ContentValues values = new ContentValues(); - values.put(MediaStore.Audio.AlbumColumns.ALBUM_ID, albumId); - values.put(MediaStore.MediaColumns.DATA, albumArtFile.getPath()); - contentResolver.insert(ALBUM_ART_URI, values); - Log.i(TAG, "Added album art: " + albumArtFile); - } - } - cursor.close(); - } + // No album art found, add it. + File albumArtFile = FileUtil.getAlbumArtFile(context, downloadFile.getSong()); + if (albumArtFile.exists()) { + ContentValues values = new ContentValues(); + values.put(MediaStore.Audio.AlbumColumns.ALBUM_ID, albumId); + values.put(MediaStore.MediaColumns.DATA, albumArtFile.getPath()); + contentResolver.insert(ALBUM_ART_URI, values); + Log.i(TAG, "Added album art: " + albumArtFile); + } + } + cursor.close(); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/service/MusicService.java b/app/src/main/java/net/nullsum/audinaut/service/MusicService.java index 25ba8d5..4f83bb3 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/MusicService.java +++ b/app/src/main/java/net/nullsum/audinaut/service/MusicService.java @@ -50,9 +50,9 @@ public interface MusicService { MusicDirectory getMusicDirectory(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception; - MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception; + MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception; - MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception; + MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception; SearchResult search(SearchCritera criteria, Context context, ProgressListener progressListener) throws Exception; @@ -61,41 +61,41 @@ public interface MusicService { List getPlaylists(boolean refresh, Context context, ProgressListener progressListener) throws Exception; void createPlaylist(String id, String name, List entries, Context context, ProgressListener progressListener) throws Exception; - - void deletePlaylist(String id, Context context, ProgressListener progressListener) throws Exception; - - void addToPlaylist(String id, List toAdd, Context context, ProgressListener progressListener) throws Exception; - - void removeFromPlaylist(String id, List toRemove, Context context, ProgressListener progressListener) throws Exception; - - void overwritePlaylist(String id, String name, int toRemove, List toAdd, Context context, ProgressListener progressListener) throws Exception; - - void updatePlaylist(String id, String name, String comment, boolean pub, Context context, ProgressListener progressListener) throws Exception; + + void deletePlaylist(String id, Context context, ProgressListener progressListener) throws Exception; + + void addToPlaylist(String id, List toAdd, Context context, ProgressListener progressListener) throws Exception; + + void removeFromPlaylist(String id, List toRemove, Context context, ProgressListener progressListener) throws Exception; + + void overwritePlaylist(String id, String name, int toRemove, List toAdd, Context context, ProgressListener progressListener) throws Exception; + + void updatePlaylist(String id, String name, String comment, boolean pub, Context context, ProgressListener progressListener) throws Exception; MusicDirectory getAlbumList(String type, int size, int offset, boolean refresh, Context context, ProgressListener progressListener) throws Exception; - MusicDirectory getAlbumList(String type, String extra, int size, int offset, boolean refresh, Context context, ProgressListener progressListener) throws Exception; + MusicDirectory getAlbumList(String type, String extra, int size, int offset, boolean refresh, Context context, ProgressListener progressListener) throws Exception; - MusicDirectory getSongList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception; + MusicDirectory getSongList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception; - MusicDirectory getRandomSongs(int size, String artistId, Context context, ProgressListener progressListener) throws Exception; + MusicDirectory getRandomSongs(int size, String artistId, Context context, ProgressListener progressListener) throws Exception; MusicDirectory getRandomSongs(int size, String folder, String genre, String startYear, String endYear, Context context, ProgressListener progressListener) throws Exception; Bitmap getCoverArt(Context context, MusicDirectory.Entry entry, int size, ProgressListener progressListener, SilentBackgroundTask task) throws Exception; Response getDownloadInputStream(Context context, MusicDirectory.Entry song, long offset, int maxBitrate, SilentBackgroundTask task) throws Exception; - List getGenres(boolean refresh, Context context, ProgressListener progressListener) throws Exception; - - MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception; + List getGenres(boolean refresh, Context context, ProgressListener progressListener) throws Exception; - User getUser(boolean refresh, String username, Context context, ProgressListener progressListener) throws Exception; + MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception; - Bitmap getBitmap(String url, int size, Context context, ProgressListener progressListener, SilentBackgroundTask task) throws Exception; + User getUser(boolean refresh, String username, Context context, ProgressListener progressListener) throws Exception; - void savePlayQueue(List songs, MusicDirectory.Entry currentPlaying, int position, Context context, ProgressListener progressListener) throws Exception; + Bitmap getBitmap(String url, int size, Context context, ProgressListener progressListener, SilentBackgroundTask task) throws Exception; - PlayerQueue getPlayQueue(Context context, ProgressListener progressListener) throws Exception; + void savePlayQueue(List songs, MusicDirectory.Entry currentPlaying, int position, Context context, ProgressListener progressListener) throws Exception; - void setInstance(Integer instance) throws Exception; + PlayerQueue getPlayQueue(Context context, ProgressListener progressListener) throws Exception; + + void setInstance(Integer instance) throws Exception; } diff --git a/app/src/main/java/net/nullsum/audinaut/service/OfflineMusicService.java b/app/src/main/java/net/nullsum/audinaut/service/OfflineMusicService.java index 598647f..8e03630 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/OfflineMusicService.java +++ b/app/src/main/java/net/nullsum/audinaut/service/OfflineMusicService.java @@ -62,19 +62,19 @@ import java.util.SortedSet; * @author Sindre Mehus */ public class OfflineMusicService implements MusicService { - private static final String TAG = OfflineMusicService.class.getSimpleName(); - private static final String ERRORMSG = "Not available in offline mode"; - private static final Random random = new Random(); + private static final String TAG = OfflineMusicService.class.getSimpleName(); + private static final String ERRORMSG = "Not available in offline mode"; + private static final Random random = new Random(); - @Override - public void ping(Context context, ProgressListener progressListener) throws Exception { + @Override + public void ping(Context context, ProgressListener progressListener) throws Exception { - } + } @Override public Indexes getIndexes(String musicFolderId, boolean refresh, Context context, ProgressListener progressListener) throws Exception { List artists = new ArrayList(); - List entries = new ArrayList<>(); + List entries = new ArrayList<>(); File root = FileUtil.getMusicDirectory(context); for (File file : FileUtil.listFiles(root)) { if (file.isDirectory()) { @@ -84,47 +84,47 @@ public class OfflineMusicService implements MusicService { artist.setName(file.getName()); artists.add(artist); } else if(!file.getName().equals("albumart.jpg") && !file.getName().equals(".nomedia")) { - entries.add(createEntry(context, file)); - } + entries.add(createEntry(context, file)); + } } - + Indexes indexes = new Indexes(0L, Collections.emptyList(), artists, entries); - return indexes; + return indexes; } @Override public MusicDirectory getMusicDirectory(String id, String artistName, boolean refresh, Context context, ProgressListener progressListener) throws Exception { return getMusicDirectory(id, artistName, refresh, context, progressListener, false); } - private MusicDirectory getMusicDirectory(String id, String artistName, boolean refresh, Context context, ProgressListener progressListener, boolean isPodcast) throws Exception { - File dir = new File(id); - MusicDirectory result = new MusicDirectory(); - result.setName(dir.getName()); + private MusicDirectory getMusicDirectory(String id, String artistName, boolean refresh, Context context, ProgressListener progressListener, boolean isPodcast) throws Exception { + File dir = new File(id); + MusicDirectory result = new MusicDirectory(); + result.setName(dir.getName()); - Set names = new HashSet(); + Set names = new HashSet(); - for (File file : FileUtil.listMediaFiles(dir)) { - String name = getName(file); - if (name != null & !names.contains(name)) { - names.add(name); - result.addChild(createEntry(context, file, name, true, isPodcast)); - } - } - result.sortChildren(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_CUSTOM_SORT_ENABLED, true)); - return result; - } + for (File file : FileUtil.listMediaFiles(dir)) { + String name = getName(file); + if (name != null & !names.contains(name)) { + names.add(name); + result.addChild(createEntry(context, file, name, true, isPodcast)); + } + } + result.sortChildren(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_CUSTOM_SORT_ENABLED, true)); + return result; + } - @Override - public MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } + @Override + public MusicDirectory getArtist(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } - @Override - public MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } + @Override + public MusicDirectory getAlbum(String id, String name, boolean refresh, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } - private String getName(File file) { + private String getName(File file) { String name = file.getName(); if (file.isDirectory()) { return name; @@ -138,401 +138,401 @@ public class OfflineMusicService implements MusicService { return FileUtil.getBaseName(name); } - private Entry createEntry(Context context, File file) { - return createEntry(context, file, getName(file)); - } - private Entry createEntry(Context context, File file, String name) { - return createEntry(context, file, name, true); - } + private Entry createEntry(Context context, File file) { + return createEntry(context, file, getName(file)); + } + private Entry createEntry(Context context, File file, String name) { + return createEntry(context, file, name, true); + } private Entry createEntry(Context context, File file, String name, boolean load) { return createEntry(context, file, name, load, false); } - private Entry createEntry(Context context, File file, String name, boolean load, boolean isPodcast) { - Entry entry; + private Entry createEntry(Context context, File file, String name, boolean load, boolean isPodcast) { + Entry entry; entry = new Entry(); - entry.setDirectory(file.isDirectory()); - entry.setId(file.getPath()); - entry.setParent(file.getParent()); - entry.setSize(file.length()); - String root = FileUtil.getMusicDirectory(context).getPath(); - if(!file.getParentFile().getParentFile().getPath().equals(root)) { - entry.setGrandParent(file.getParentFile().getParent()); - } - entry.setPath(file.getPath().replaceFirst("^" + root + "/" , "")); - String title = name; - if (file.isFile()) { - File artistFolder = file.getParentFile().getParentFile(); - File albumFolder = file.getParentFile(); - if(artistFolder.getPath().equals(root)) { - entry.setArtist(albumFolder.getName()); - } else { - entry.setArtist(artistFolder.getName()); - } - entry.setAlbum(albumFolder.getName()); + entry.setDirectory(file.isDirectory()); + entry.setId(file.getPath()); + entry.setParent(file.getParent()); + entry.setSize(file.length()); + String root = FileUtil.getMusicDirectory(context).getPath(); + if(!file.getParentFile().getParentFile().getPath().equals(root)) { + entry.setGrandParent(file.getParentFile().getParent()); + } + entry.setPath(file.getPath().replaceFirst("^" + root + "/" , "")); + String title = name; + if (file.isFile()) { + File artistFolder = file.getParentFile().getParentFile(); + File albumFolder = file.getParentFile(); + if(artistFolder.getPath().equals(root)) { + entry.setArtist(albumFolder.getName()); + } else { + entry.setArtist(artistFolder.getName()); + } + entry.setAlbum(albumFolder.getName()); - int index = name.indexOf('-'); - if(index != -1) { - try { - entry.setTrack(Integer.parseInt(name.substring(0, index))); - title = title.substring(index + 1); - } catch(Exception e) { - // Failed parseInt, just means track filled out - } - } + int index = name.indexOf('-'); + if(index != -1) { + try { + entry.setTrack(Integer.parseInt(name.substring(0, index))); + title = title.substring(index + 1); + } catch(Exception e) { + // Failed parseInt, just means track filled out + } + } - if(load) { - entry.loadMetadata(file); - } - } + if(load) { + entry.loadMetadata(file); + } + } - entry.setTitle(title); - entry.setSuffix(FileUtil.getExtension(file.getName().replace(".complete", ""))); + entry.setTitle(title); + entry.setSuffix(FileUtil.getExtension(file.getName().replace(".complete", ""))); - File albumArt = FileUtil.getAlbumArtFile(context, entry); - if (albumArt.exists()) { - entry.setCoverArt(albumArt.getPath()); - } - return entry; - } + File albumArt = FileUtil.getAlbumArtFile(context, entry); + if (albumArt.exists()) { + entry.setCoverArt(albumArt.getPath()); + } + return entry; + } @Override public Bitmap getCoverArt(Context context, Entry entry, int size, ProgressListener progressListener, SilentBackgroundTask task) throws Exception { - try { - return FileUtil.getAlbumArtBitmap(context, entry, size); - } catch(Exception e) { - return null; - } + try { + return FileUtil.getAlbumArtBitmap(context, entry, size); + } catch(Exception e) { + return null; + } } - @Override - public Response getDownloadInputStream(Context context, Entry song, long offset, int maxBitrate, SilentBackgroundTask task) throws Exception { - throw new OfflineException(ERRORMSG); - } + @Override + public Response getDownloadInputStream(Context context, Entry song, long offset, int maxBitrate, SilentBackgroundTask task) throws Exception { + throw new OfflineException(ERRORMSG); + } - @Override + @Override public List getMusicFolders(boolean refresh, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); + throw new OfflineException(ERRORMSG); } - @Override + @Override public SearchResult search(SearchCritera criteria, Context context, ProgressListener progressListener) throws Exception { - List artists = new ArrayList(); - List albums = new ArrayList(); - List songs = new ArrayList(); + List artists = new ArrayList(); + List albums = new ArrayList(); + List songs = new ArrayList(); File root = FileUtil.getMusicDirectory(context); - int closeness = 0; + int closeness = 0; for (File artistFile : FileUtil.listFiles(root)) { - String artistName = artistFile.getName(); + String artistName = artistFile.getName(); if (artistFile.isDirectory()) { - if((closeness = matchCriteria(criteria, artistName)) > 0) { - Artist artist = new Artist(); - artist.setId(artistFile.getPath()); - artist.setIndex(artistFile.getName().substring(0, 1)); - artist.setName(artistName); - artist.setCloseness(closeness); - artists.add(artist); - } - - recursiveAlbumSearch(artistName, artistFile, criteria, context, albums, songs); + if((closeness = matchCriteria(criteria, artistName)) > 0) { + Artist artist = new Artist(); + artist.setId(artistFile.getPath()); + artist.setIndex(artistFile.getName().substring(0, 1)); + artist.setName(artistName); + artist.setCloseness(closeness); + artists.add(artist); + } + + recursiveAlbumSearch(artistName, artistFile, criteria, context, albums, songs); } } - - Collections.sort(artists, new Comparator() { - public int compare(Artist lhs, Artist rhs) { - if(lhs.getCloseness() == rhs.getCloseness()) { - return 0; - } - else if(lhs.getCloseness() > rhs.getCloseness()) { - return -1; - } - else { - return 1; - } - } - }); - Collections.sort(albums, new Comparator() { - public int compare(Entry lhs, Entry rhs) { - if(lhs.getCloseness() == rhs.getCloseness()) { - return 0; - } - else if(lhs.getCloseness() > rhs.getCloseness()) { - return -1; - } - else { - return 1; - } - } - }); - Collections.sort(songs, new Comparator() { - public int compare(Entry lhs, Entry rhs) { - if(lhs.getCloseness() == rhs.getCloseness()) { - return 0; - } - else if(lhs.getCloseness() > rhs.getCloseness()) { - return -1; - } - else { - return 1; - } - } - }); - // Respect counts in search criteria - int artistCount = Math.min(artists.size(), criteria.getArtistCount()); - int albumCount = Math.min(albums.size(), criteria.getAlbumCount()); - int songCount = Math.min(songs.size(), criteria.getSongCount()); - artists = artists.subList(0, artistCount); - albums = albums.subList(0, albumCount); - songs = songs.subList(0, songCount); + Collections.sort(artists, new Comparator() { + public int compare(Artist lhs, Artist rhs) { + if(lhs.getCloseness() == rhs.getCloseness()) { + return 0; + } + else if(lhs.getCloseness() > rhs.getCloseness()) { + return -1; + } + else { + return 1; + } + } + }); + Collections.sort(albums, new Comparator() { + public int compare(Entry lhs, Entry rhs) { + if(lhs.getCloseness() == rhs.getCloseness()) { + return 0; + } + else if(lhs.getCloseness() > rhs.getCloseness()) { + return -1; + } + else { + return 1; + } + } + }); + Collections.sort(songs, new Comparator() { + public int compare(Entry lhs, Entry rhs) { + if(lhs.getCloseness() == rhs.getCloseness()) { + return 0; + } + else if(lhs.getCloseness() > rhs.getCloseness()) { + return -1; + } + else { + return 1; + } + } + }); - return new SearchResult(artists, albums, songs); + // Respect counts in search criteria + int artistCount = Math.min(artists.size(), criteria.getArtistCount()); + int albumCount = Math.min(albums.size(), criteria.getAlbumCount()); + int songCount = Math.min(songs.size(), criteria.getSongCount()); + artists = artists.subList(0, artistCount); + albums = albums.subList(0, albumCount); + songs = songs.subList(0, songCount); + + return new SearchResult(artists, albums, songs); } - private void recursiveAlbumSearch(String artistName, File file, SearchCritera criteria, Context context, List albums, List songs) { - int closeness; - for(File albumFile : FileUtil.listMediaFiles(file)) { - if(albumFile.isDirectory()) { - String albumName = getName(albumFile); - if((closeness = matchCriteria(criteria, albumName)) > 0) { - Entry album = createEntry(context, albumFile, albumName); - album.setArtist(artistName); - album.setCloseness(closeness); - albums.add(album); - } + private void recursiveAlbumSearch(String artistName, File file, SearchCritera criteria, Context context, List albums, List songs) { + int closeness; + for(File albumFile : FileUtil.listMediaFiles(file)) { + if(albumFile.isDirectory()) { + String albumName = getName(albumFile); + if((closeness = matchCriteria(criteria, albumName)) > 0) { + Entry album = createEntry(context, albumFile, albumName); + album.setArtist(artistName); + album.setCloseness(closeness); + albums.add(album); + } - for(File songFile : FileUtil.listMediaFiles(albumFile)) { - String songName = getName(songFile); - if(songName == null) { - continue; - } + for(File songFile : FileUtil.listMediaFiles(albumFile)) { + String songName = getName(songFile); + if(songName == null) { + continue; + } - if(songFile.isDirectory()) { - recursiveAlbumSearch(artistName, songFile, criteria, context, albums, songs); - } - else if((closeness = matchCriteria(criteria, songName)) > 0){ - Entry song = createEntry(context, albumFile, songName); - song.setArtist(artistName); - song.setAlbum(albumName); - song.setCloseness(closeness); - songs.add(song); - } - } - } - else { - String songName = getName(albumFile); - if((closeness = matchCriteria(criteria, songName)) > 0) { - Entry song = createEntry(context, albumFile, songName); - song.setArtist(artistName); - song.setAlbum(songName); - song.setCloseness(closeness); - songs.add(song); - } - } - } - } - private int matchCriteria(SearchCritera criteria, String name) { - if (criteria.getPattern().matcher(name).matches()) { - return Util.getStringDistance( - criteria.getQuery().toLowerCase(), - name.toLowerCase()); - } else { - return 0; - } - } + if(songFile.isDirectory()) { + recursiveAlbumSearch(artistName, songFile, criteria, context, albums, songs); + } + else if((closeness = matchCriteria(criteria, songName)) > 0){ + Entry song = createEntry(context, albumFile, songName); + song.setArtist(artistName); + song.setAlbum(albumName); + song.setCloseness(closeness); + songs.add(song); + } + } + } + else { + String songName = getName(albumFile); + if((closeness = matchCriteria(criteria, songName)) > 0) { + Entry song = createEntry(context, albumFile, songName); + song.setArtist(artistName); + song.setAlbum(songName); + song.setCloseness(closeness); + songs.add(song); + } + } + } + } + private int matchCriteria(SearchCritera criteria, String name) { + if (criteria.getPattern().matcher(name).matches()) { + return Util.getStringDistance( + criteria.getQuery().toLowerCase(), + name.toLowerCase()); + } else { + return 0; + } + } @Override public List getPlaylists(boolean refresh, Context context, ProgressListener progressListener) throws Exception { List playlists = new ArrayList(); File root = FileUtil.getPlaylistDirectory(context); - String lastServer = null; - boolean removeServer = true; + String lastServer = null; + boolean removeServer = true; for (File folder : FileUtil.listFiles(root)) { - if(folder.isDirectory()) { - String server = folder.getName(); - SortedSet fileList = FileUtil.listFiles(folder); - for(File file: fileList) { - if(FileUtil.isPlaylistFile(file)) { - String id = file.getName(); - String filename = FileUtil.getBaseName(id); - String name = server + ": " + filename; - Playlist playlist = new Playlist(server, name); - playlist.setComment(filename); + if(folder.isDirectory()) { + String server = folder.getName(); + SortedSet fileList = FileUtil.listFiles(folder); + for(File file: fileList) { + if(FileUtil.isPlaylistFile(file)) { + String id = file.getName(); + String filename = FileUtil.getBaseName(id); + String name = server + ": " + filename; + Playlist playlist = new Playlist(server, name); + playlist.setComment(filename); - Reader reader = null; - BufferedReader buffer = null; - int songCount = 0; - try { - reader = new FileReader(file); - buffer = new BufferedReader(reader); + Reader reader = null; + BufferedReader buffer = null; + int songCount = 0; + try { + reader = new FileReader(file); + buffer = new BufferedReader(reader); - String line = buffer.readLine(); - while( (line = buffer.readLine()) != null ){ - // No matter what, end file can't have .complete in it - line = line.replace(".complete", ""); - File entryFile = new File(line); + String line = buffer.readLine(); + while( (line = buffer.readLine()) != null ){ + // No matter what, end file can't have .complete in it + line = line.replace(".complete", ""); + File entryFile = new File(line); - // Don't add file to playlist if it doesn't exist as cached or pinned! - File checkFile = entryFile; - if(!checkFile.exists()) { - // If normal file doens't exist, check if .complete version does - checkFile = new File(entryFile.getParent(), FileUtil.getBaseName(entryFile.getName()) - + ".complete." + FileUtil.getExtension(entryFile.getName())); - } + // Don't add file to playlist if it doesn't exist as cached or pinned! + File checkFile = entryFile; + if(!checkFile.exists()) { + // If normal file doens't exist, check if .complete version does + checkFile = new File(entryFile.getParent(), FileUtil.getBaseName(entryFile.getName()) + + ".complete." + FileUtil.getExtension(entryFile.getName())); + } - String entryName = getName(entryFile); - if(checkFile.exists() && entryName != null){ - songCount++; - } - } + String entryName = getName(entryFile); + if(checkFile.exists() && entryName != null){ + songCount++; + } + } - playlist.setSongCount(Integer.toString(songCount)); - } catch(Exception e) { - Log.w(TAG, "Failed to count songs in playlist", e); - } finally { - Util.close(buffer); - Util.close(reader); - } + playlist.setSongCount(Integer.toString(songCount)); + } catch(Exception e) { + Log.w(TAG, "Failed to count songs in playlist", e); + } finally { + Util.close(buffer); + Util.close(reader); + } - if(songCount > 0) { - playlists.add(playlist); - } - } - } - - if(!server.equals(lastServer) && fileList.size() > 0) { - if(lastServer != null) { - removeServer = false; - } - lastServer = server; - } - } else { - // Delete legacy playlist files - try { - folder.delete(); - } catch(Exception e) { - Log.w(TAG, "Failed to delete old playlist file: " + folder.getName()); - } - } + if(songCount > 0) { + playlists.add(playlist); + } + } + } + + if(!server.equals(lastServer) && fileList.size() > 0) { + if(lastServer != null) { + removeServer = false; + } + lastServer = server; + } + } else { + // Delete legacy playlist files + try { + folder.delete(); + } catch(Exception e) { + Log.w(TAG, "Failed to delete old playlist file: " + folder.getName()); + } + } + } + + if(removeServer) { + for(Playlist playlist: playlists) { + playlist.setName(playlist.getName().substring(playlist.getId().length() + 2)); + } } - - if(removeServer) { - for(Playlist playlist: playlists) { - playlist.setName(playlist.getName().substring(playlist.getId().length() + 2)); - } - } return playlists; } @Override public MusicDirectory getPlaylist(boolean refresh, String id, String name, Context context, ProgressListener progressListener) throws Exception { - DownloadService downloadService = DownloadService.getInstance(); + DownloadService downloadService = DownloadService.getInstance(); if (downloadService == null) { return new MusicDirectory(); } - + Reader reader = null; - BufferedReader buffer = null; - try { - int firstIndex = name.indexOf(id); - if(firstIndex != -1) { - name = name.substring(id.length() + 2); - } - - File playlistFile = FileUtil.getPlaylistFile(context, id, name); - reader = new FileReader(playlistFile); - buffer = new BufferedReader(reader); - - MusicDirectory playlist = new MusicDirectory(); - String line = buffer.readLine(); - if(!"#EXTM3U".equals(line)) return playlist; - - while( (line = buffer.readLine()) != null ){ - // No matter what, end file can't have .complete in it - line = line.replace(".complete", ""); - File entryFile = new File(line); - - // Don't add file to playlist if it doesn't exist as cached or pinned! - File checkFile = entryFile; - if(!checkFile.exists()) { - // If normal file doens't exist, check if .complete version does - checkFile = new File(entryFile.getParent(), FileUtil.getBaseName(entryFile.getName()) - + ".complete." + FileUtil.getExtension(entryFile.getName())); - } - - String entryName = getName(entryFile); - if(checkFile.exists() && entryName != null){ - playlist.addChild(createEntry(context, entryFile, entryName, false)); - } - } - - return playlist; - } finally { - Util.close(buffer); - Util.close(reader); - } + BufferedReader buffer = null; + try { + int firstIndex = name.indexOf(id); + if(firstIndex != -1) { + name = name.substring(id.length() + 2); + } + + File playlistFile = FileUtil.getPlaylistFile(context, id, name); + reader = new FileReader(playlistFile); + buffer = new BufferedReader(reader); + + MusicDirectory playlist = new MusicDirectory(); + String line = buffer.readLine(); + if(!"#EXTM3U".equals(line)) return playlist; + + while( (line = buffer.readLine()) != null ){ + // No matter what, end file can't have .complete in it + line = line.replace(".complete", ""); + File entryFile = new File(line); + + // Don't add file to playlist if it doesn't exist as cached or pinned! + File checkFile = entryFile; + if(!checkFile.exists()) { + // If normal file doens't exist, check if .complete version does + checkFile = new File(entryFile.getParent(), FileUtil.getBaseName(entryFile.getName()) + + ".complete." + FileUtil.getExtension(entryFile.getName())); + } + + String entryName = getName(entryFile); + if(checkFile.exists() && entryName != null){ + playlist.addChild(createEntry(context, entryFile, entryName, false)); + } + } + + return playlist; + } finally { + Util.close(buffer); + Util.close(reader); + } } @Override public void createPlaylist(String id, String name, List entries, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); + throw new OfflineException(ERRORMSG); + } + + @Override + public void deletePlaylist(String id, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } + + @Override + public void addToPlaylist(String id, List toAdd, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } + + @Override + public void removeFromPlaylist(String id, List toRemove, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } + + @Override + public void overwritePlaylist(String id, String name, int toRemove, List toAdd, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } + + @Override + public void updatePlaylist(String id, String name, String comment, boolean pub, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); } - - @Override - public void deletePlaylist(String id, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } - - @Override - public void addToPlaylist(String id, List toAdd, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } - - @Override - public void removeFromPlaylist(String id, List toRemove, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } - - @Override - public void overwritePlaylist(String id, String name, int toRemove, List toAdd, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } - - @Override - public void updatePlaylist(String id, String name, String comment, boolean pub, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } @Override public MusicDirectory getAlbumList(String type, int size, int offset, boolean refresh, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); + throw new OfflineException(ERRORMSG); } - @Override - public MusicDirectory getAlbumList(String type, String extra, int size, int offset, boolean refresh, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } + @Override + public MusicDirectory getAlbumList(String type, String extra, int size, int offset, boolean refresh, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } - @Override - public MusicDirectory getSongList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } + @Override + public MusicDirectory getSongList(String type, int size, int offset, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } - @Override - public MusicDirectory getRandomSongs(int size, String artistId, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } + @Override + public MusicDirectory getRandomSongs(int size, String artistId, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } - @Override - public List getGenres(boolean refresh, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } - - @Override - public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } + @Override + public List getGenres(boolean refresh, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } - @Override + @Override + public MusicDirectory getSongsByGenre(String genre, int count, int offset, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } + + @Override public MusicDirectory getRandomSongs(int size, String folder, String genre, String startYear, String endYear, Context context, ProgressListener progressListener) throws Exception { File root = FileUtil.getMusicDirectory(context); List children = new LinkedList(); @@ -550,29 +550,29 @@ public class OfflineMusicService implements MusicService { return result; } - @Override - public User getUser(boolean refresh, String username, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } + @Override + public User getUser(boolean refresh, String username, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } - @Override - public Bitmap getBitmap(String url, int size, Context context, ProgressListener progressListener, SilentBackgroundTask task) throws Exception { - throw new OfflineException(ERRORMSG); - } + @Override + public Bitmap getBitmap(String url, int size, Context context, ProgressListener progressListener, SilentBackgroundTask task) throws Exception { + throw new OfflineException(ERRORMSG); + } - @Override - public void savePlayQueue(List songs, Entry currentPlaying, int position, Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } + @Override + public void savePlayQueue(List songs, Entry currentPlaying, int position, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } - @Override - public PlayerQueue getPlayQueue(Context context, ProgressListener progressListener) throws Exception { - throw new OfflineException(ERRORMSG); - } + @Override + public PlayerQueue getPlayQueue(Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } @Override public void setInstance(Integer instance) throws Exception{ - throw new OfflineException(ERRORMSG); + throw new OfflineException(ERRORMSG); } private void listFilesRecursively(File parent, List children) { diff --git a/app/src/main/java/net/nullsum/audinaut/service/parser/EntryListParser.java b/app/src/main/java/net/nullsum/audinaut/service/parser/EntryListParser.java index d5511c8..62bea2c 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/parser/EntryListParser.java +++ b/app/src/main/java/net/nullsum/audinaut/service/parser/EntryListParser.java @@ -45,10 +45,10 @@ public class EntryListParser extends MusicDirectoryEntryParser { if (eventType == XmlPullParser.START_TAG) { String name = getElementName(); if ("album".equals(name)) { - MusicDirectory.Entry entry = parseEntry(""); - if(get("isDir") == null) { - entry.setDirectory(true); - } + MusicDirectory.Entry entry = parseEntry(""); + if(get("isDir") == null) { + entry.setDirectory(true); + } dir.addChild(entry); } else if ("song".equals(name)) { MusicDirectory.Entry entry = parseEntry(""); diff --git a/app/src/main/java/net/nullsum/audinaut/service/parser/ErrorParser.java b/app/src/main/java/net/nullsum/audinaut/service/parser/ErrorParser.java index ce367d4..c6a866c 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/parser/ErrorParser.java +++ b/app/src/main/java/net/nullsum/audinaut/service/parser/ErrorParser.java @@ -29,8 +29,8 @@ import java.io.InputStream; public class ErrorParser extends AbstractParser { public ErrorParser(Context context, int instance) { - super(context, instance); - } + super(context, instance); + } public void parse(InputStream inputStream) throws Exception { diff --git a/app/src/main/java/net/nullsum/audinaut/service/parser/IndexesParser.java b/app/src/main/java/net/nullsum/audinaut/service/parser/IndexesParser.java index 9820e7b..2ec8b0d 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/parser/IndexesParser.java +++ b/app/src/main/java/net/nullsum/audinaut/service/parser/IndexesParser.java @@ -53,13 +53,13 @@ public class IndexesParser extends MusicDirectoryEntryParser { List artists = new ArrayList(); List shortcuts = new ArrayList(); - List entries = new ArrayList(); + List entries = new ArrayList(); Long lastModified = null; int eventType; String index = "#"; - String ignoredArticles = null; + String ignoredArticles = null; boolean changed = false; - Map artistList = new HashMap(); + Map artistList = new HashMap(); do { eventType = nextParseEvent(); @@ -68,7 +68,7 @@ public class IndexesParser extends MusicDirectoryEntryParser { if ("indexes".equals(name) || "artists".equals(name)) { changed = true; lastModified = getLong("lastModified"); - ignoredArticles = get("ignoredArticles"); + ignoredArticles = get("ignoredArticles"); } else if ("index".equals(name)) { index = get("name"); @@ -78,14 +78,14 @@ public class IndexesParser extends MusicDirectoryEntryParser { artist.setName(get("name")); artist.setIndex(index); - // Combine the id's for the two artists - if(artistList.containsKey(artist.getName())) { - Artist originalArtist = artistList.get(artist.getName()); - originalArtist.setId(originalArtist.getId() + ";" + artist.getId()); - } else { - artistList.put(artist.getName(), artist); - artists.add(artist); - } + // Combine the id's for the two artists + if(artistList.containsKey(artist.getName())) { + Artist originalArtist = artistList.get(artist.getName()); + originalArtist.setId(originalArtist.getId() + ";" + artist.getId()); + } else { + artistList.put(artist.getName(), artist); + artists.add(artist); + } if (artists.size() % 10 == 0) { String msg = getContext().getResources().getString(R.string.parser_artist_count, artists.size()); @@ -97,22 +97,22 @@ public class IndexesParser extends MusicDirectoryEntryParser { shortcut.setName(get("name")); shortcut.setIndex("*"); shortcuts.add(shortcut); - } else if("child".equals(name)) { - MusicDirectory.Entry entry = parseEntry(""); - entries.add(entry); - } else if ("error".equals(name)) { + } else if("child".equals(name)) { + MusicDirectory.Entry entry = parseEntry(""); + entries.add(entry); + } else if ("error".equals(name)) { handleError(); } } } while (eventType != XmlPullParser.END_DOCUMENT); validate(); - - if(ignoredArticles != null) { - SharedPreferences.Editor prefs = Util.getPreferences(context).edit(); - prefs.putString(Constants.CACHE_KEY_IGNORE, ignoredArticles); - prefs.apply(); - } + + if(ignoredArticles != null) { + SharedPreferences.Editor prefs = Util.getPreferences(context).edit(); + prefs.putString(Constants.CACHE_KEY_IGNORE, ignoredArticles); + prefs.apply(); + } if (!changed) { return null; diff --git a/app/src/main/java/net/nullsum/audinaut/service/parser/MusicDirectoryEntryParser.java b/app/src/main/java/net/nullsum/audinaut/service/parser/MusicDirectoryEntryParser.java index 8e0ca9d..a669308 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/parser/MusicDirectoryEntryParser.java +++ b/app/src/main/java/net/nullsum/audinaut/service/parser/MusicDirectoryEntryParser.java @@ -33,21 +33,21 @@ public class MusicDirectoryEntryParser extends AbstractParser { protected MusicDirectory.Entry parseEntry(String artist) { MusicDirectory.Entry entry = new MusicDirectory.Entry(); entry.setId(get("id")); - entry.setParent(get("parent")); - entry.setArtistId(get("artistId")); + entry.setParent(get("parent")); + entry.setArtistId(get("artistId")); entry.setTitle(get("title")); - if(entry.getTitle() == null) { - entry.setTitle(get("name")); - } + if(entry.getTitle() == null) { + entry.setTitle(get("name")); + } entry.setDirectory(getBoolean("isDir")); entry.setCoverArt(get("coverArt")); entry.setArtist(get("artist")); entry.setYear(getInteger("year")); entry.setGenre(get("genre")); - entry.setAlbum(get("album")); + entry.setAlbum(get("album")); if (!entry.isDirectory()) { - entry.setAlbumId(get("albumId")); + entry.setAlbumId(get("albumId")); entry.setTrack(getInteger("track")); entry.setContentType(get("contentType")); entry.setSuffix(get("suffix")); @@ -57,23 +57,23 @@ public class MusicDirectoryEntryParser extends AbstractParser { entry.setDuration(getInteger("duration")); entry.setBitRate(getInteger("bitRate")); entry.setPath(get("path")); - entry.setDiscNumber(getInteger("discNumber")); + entry.setDiscNumber(getInteger("discNumber")); - String type = get("type"); + String type = get("type"); } else if(!"".equals(artist)) { - entry.setPath(artist + "/" + entry.getTitle()); - } + entry.setPath(artist + "/" + entry.getTitle()); + } + return entry; + } + + protected MusicDirectory.Entry parseArtist() { + MusicDirectory.Entry entry = new MusicDirectory.Entry(); + + entry.setId(get("id")); + entry.setTitle(get("name")); + entry.setPath(entry.getTitle()); + entry.setDirectory(true); + return entry; } - - protected MusicDirectory.Entry parseArtist() { - MusicDirectory.Entry entry = new MusicDirectory.Entry(); - - entry.setId(get("id")); - entry.setTitle(get("name")); - entry.setPath(entry.getTitle()); - entry.setDirectory(true); - - return entry; - } } diff --git a/app/src/main/java/net/nullsum/audinaut/service/parser/MusicDirectoryParser.java b/app/src/main/java/net/nullsum/audinaut/service/parser/MusicDirectoryParser.java index 43b628c..8cde6ed 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/parser/MusicDirectoryParser.java +++ b/app/src/main/java/net/nullsum/audinaut/service/parser/MusicDirectoryParser.java @@ -49,52 +49,52 @@ public class MusicDirectoryParser extends MusicDirectoryEntryParser { MusicDirectory dir = new MusicDirectory(); int eventType; - boolean isArtist = false; - Map titleMap = new HashMap(); + boolean isArtist = false; + Map titleMap = new HashMap(); do { eventType = nextParseEvent(); if (eventType == XmlPullParser.START_TAG) { String name = getElementName(); if ("child".equals(name) || "song".equals(name)) { - Entry entry = parseEntry(artist); - entry.setGrandParent(dir.getParent()); + Entry entry = parseEntry(artist); + entry.setGrandParent(dir.getParent()); - // Only check for songs - if(!entry.isDirectory()) { - // Check if duplicates - String disc = (entry.getDiscNumber() != null) ? Integer.toString(entry.getDiscNumber()) : ""; - String track = (entry.getTrack() != null) ? Integer.toString(entry.getTrack()) : ""; - String duplicateId = disc + "-" + track + "-" + entry.getTitle(); + // Only check for songs + if(!entry.isDirectory()) { + // Check if duplicates + String disc = (entry.getDiscNumber() != null) ? Integer.toString(entry.getDiscNumber()) : ""; + String track = (entry.getTrack() != null) ? Integer.toString(entry.getTrack()) : ""; + String duplicateId = disc + "-" + track + "-" + entry.getTitle(); - Entry duplicate = titleMap.get(duplicateId); - if (duplicate != null) { - // Check if the first already has been rebased or not - if (duplicate.getTitle().equals(entry.getTitle())) { - duplicate.rebaseTitleOffPath(); - } + Entry duplicate = titleMap.get(duplicateId); + if (duplicate != null) { + // Check if the first already has been rebased or not + if (duplicate.getTitle().equals(entry.getTitle())) { + duplicate.rebaseTitleOffPath(); + } - // Rebase if this is the second instance of this title found - entry.rebaseTitleOffPath(); - } else { - titleMap.put(duplicateId, entry); - } - } + // Rebase if this is the second instance of this title found + entry.rebaseTitleOffPath(); + } else { + titleMap.put(duplicateId, entry); + } + } dir.addChild(entry); } else if ("directory".equals(name) || "artist".equals(name) || ("album".equals(name) && !isArtist)) { dir.setName(get("name")); - dir.setId(get("id")); - if(Util.isTagBrowsing(context, instance)) { - dir.setParent(get("artistId")); - } else { - dir.setParent(get("parent")); - } - isArtist = true; + dir.setId(get("id")); + if(Util.isTagBrowsing(context, instance)) { + dir.setParent(get("artistId")); + } else { + dir.setParent(get("parent")); + } + isArtist = true; } else if("album".equals(name)) { - Entry entry = parseEntry(artist); - entry.setDirectory(true); - dir.addChild(entry); - } else if ("error".equals(name)) { + Entry entry = parseEntry(artist); + entry.setDirectory(true); + dir.addChild(entry); + } else if ("error".equals(name)) { handleError(); } } diff --git a/app/src/main/java/net/nullsum/audinaut/service/parser/PlayQueueParser.java b/app/src/main/java/net/nullsum/audinaut/service/parser/PlayQueueParser.java index c8fef8d..9b86944 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/parser/PlayQueueParser.java +++ b/app/src/main/java/net/nullsum/audinaut/service/parser/PlayQueueParser.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.service.parser; @@ -30,54 +30,54 @@ import net.nullsum.audinaut.domain.PlayerQueue; import net.nullsum.audinaut.util.ProgressListener; public class PlayQueueParser extends MusicDirectoryEntryParser { - private static final String TAG = PlayQueueParser.class.getSimpleName(); + private static final String TAG = PlayQueueParser.class.getSimpleName(); - public PlayQueueParser(Context context, int instance) { - super(context, instance); - } + public PlayQueueParser(Context context, int instance) { + super(context, instance); + } - public PlayerQueue parse(InputStream inputStream, ProgressListener progressListener) throws Exception { - init(inputStream); + public PlayerQueue parse(InputStream inputStream, ProgressListener progressListener) throws Exception { + init(inputStream); - PlayerQueue state = new PlayerQueue(); - String currentId = null; - int eventType; - do { - eventType = nextParseEvent(); - if (eventType == XmlPullParser.START_TAG) { - String name = getElementName(); - if("playQueue".equals(name)) { - currentId = get("current"); - state.currentPlayingPosition = getInteger("position"); - try { - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH); - dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - state.changed = dateFormat.parse(get("changed")); - } catch (ParseException e) { - state.changed = null; - } - } else if ("entry".equals(name)) { - MusicDirectory.Entry entry = parseEntry(""); - // Only add songs + PlayerQueue state = new PlayerQueue(); + String currentId = null; + int eventType; + do { + eventType = nextParseEvent(); + if (eventType == XmlPullParser.START_TAG) { + String name = getElementName(); + if("playQueue".equals(name)) { + currentId = get("current"); + state.currentPlayingPosition = getInteger("position"); + try { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH); + dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + state.changed = dateFormat.parse(get("changed")); + } catch (ParseException e) { + state.changed = null; + } + } else if ("entry".equals(name)) { + MusicDirectory.Entry entry = parseEntry(""); + // Only add songs state.songs.add(entry); - } else if ("error".equals(name)) { - handleError(); - } - } - } while (eventType != XmlPullParser.END_DOCUMENT); + } else if ("error".equals(name)) { + handleError(); + } + } + } while (eventType != XmlPullParser.END_DOCUMENT); - if(currentId != null) { - for (MusicDirectory.Entry entry : state.songs) { - if (entry.getId().equals(currentId)) { - state.currentPlayingIndex = state.songs.indexOf(entry); - } - } - } else { - state.currentPlayingIndex = 0; - state.currentPlayingPosition = 0; - } + if(currentId != null) { + for (MusicDirectory.Entry entry : state.songs) { + if (entry.getId().equals(currentId)) { + state.currentPlayingIndex = state.songs.indexOf(entry); + } + } + } else { + state.currentPlayingIndex = 0; + state.currentPlayingPosition = 0; + } - validate(); - return state; - } + validate(); + return state; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/service/parser/PlaylistParser.java b/app/src/main/java/net/nullsum/audinaut/service/parser/PlaylistParser.java index 79d3422..7add8ce 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/parser/PlaylistParser.java +++ b/app/src/main/java/net/nullsum/audinaut/service/parser/PlaylistParser.java @@ -32,8 +32,8 @@ import java.io.InputStream; public class PlaylistParser extends MusicDirectoryEntryParser { public PlaylistParser(Context context, int instance) { - super(context, instance); - } + super(context, instance); + } public MusicDirectory parse(InputStream inputStream, ProgressListener progressListener) throws Exception { init(inputStream); @@ -49,9 +49,9 @@ public class PlaylistParser extends MusicDirectoryEntryParser { } else if ("error".equals(name)) { handleError(); } else if ("playlist".equals(name)) { - dir.setName(get("name")); - dir.setId(get("id")); - } + dir.setName(get("name")); + dir.setId(get("id")); + } } } while (eventType != XmlPullParser.END_DOCUMENT); diff --git a/app/src/main/java/net/nullsum/audinaut/service/parser/PlaylistsParser.java b/app/src/main/java/net/nullsum/audinaut/service/parser/PlaylistsParser.java index 1db2ef9..5444819 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/parser/PlaylistsParser.java +++ b/app/src/main/java/net/nullsum/audinaut/service/parser/PlaylistsParser.java @@ -34,8 +34,8 @@ import java.util.List; public class PlaylistsParser extends AbstractParser { public PlaylistsParser(Context context, int instance) { - super(context, instance); - } + super(context, instance); + } public List parse(InputStream inputStream, ProgressListener progressListener) throws Exception { init(inputStream); @@ -49,13 +49,13 @@ public class PlaylistsParser extends AbstractParser { if ("playlist".equals(tag)) { String id = get("id"); String name = get("name"); - String owner = get("owner"); - String comment = get("comment"); - String songCount = get("songCount"); - String pub = get("public"); - String created = get("created"); - String changed = get("changed"); - Integer duration = getInteger("duration"); + String owner = get("owner"); + String comment = get("comment"); + String songCount = get("songCount"); + String pub = get("public"); + String created = get("created"); + String changed = get("changed"); + Integer duration = getInteger("duration"); result.add(new Playlist(id, name, owner, comment, songCount, pub, created, changed, duration)); } else if ("error".equals(tag)) { handleError(); diff --git a/app/src/main/java/net/nullsum/audinaut/service/parser/RandomSongsParser.java b/app/src/main/java/net/nullsum/audinaut/service/parser/RandomSongsParser.java index c85acfb..20691a3 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/parser/RandomSongsParser.java +++ b/app/src/main/java/net/nullsum/audinaut/service/parser/RandomSongsParser.java @@ -32,8 +32,8 @@ import java.io.InputStream; public class RandomSongsParser extends MusicDirectoryEntryParser { public RandomSongsParser(Context context, int instance) { - super(context, instance); - } + super(context, instance); + } public MusicDirectory parse(InputStream inputStream, ProgressListener progressListener) throws Exception { init(inputStream); diff --git a/app/src/main/java/net/nullsum/audinaut/service/parser/SearchResult2Parser.java b/app/src/main/java/net/nullsum/audinaut/service/parser/SearchResult2Parser.java index 831a0e3..59c9298 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/parser/SearchResult2Parser.java +++ b/app/src/main/java/net/nullsum/audinaut/service/parser/SearchResult2Parser.java @@ -36,8 +36,8 @@ import java.util.ArrayList; public class SearchResult2Parser extends MusicDirectoryEntryParser { public SearchResult2Parser(Context context, int instance) { - super(context, instance); - } + super(context, instance); + } public SearchResult parse(InputStream inputStream, ProgressListener progressListener) throws Exception { init(inputStream); @@ -56,8 +56,8 @@ public class SearchResult2Parser extends MusicDirectoryEntryParser { artist.setName(get("name")); artists.add(artist); } else if ("album".equals(name)) { - MusicDirectory.Entry entry = parseEntry(""); - entry.setDirectory(true); + MusicDirectory.Entry entry = parseEntry(""); + entry.setDirectory(true); albums.add(entry); } else if ("song".equals(name)) { songs.add(parseEntry("")); diff --git a/app/src/main/java/net/nullsum/audinaut/service/parser/UserParser.java b/app/src/main/java/net/nullsum/audinaut/service/parser/UserParser.java index 9cb2875..efe5c33 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/parser/UserParser.java +++ b/app/src/main/java/net/nullsum/audinaut/service/parser/UserParser.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.service.parser; @@ -33,76 +33,76 @@ import net.nullsum.audinaut.service.MusicServiceFactory; import net.nullsum.audinaut.util.ProgressListener; public class UserParser extends AbstractParser { - private static final String TAG = UserParser.class.getSimpleName(); + private static final String TAG = UserParser.class.getSimpleName(); - public UserParser(Context context, int instance) { - super(context, instance); - } + public UserParser(Context context, int instance) { + super(context, instance); + } - public List parse(InputStream inputStream, ProgressListener progressListener) throws Exception { - init(inputStream); - List result = new ArrayList(); - List musicFolders = null; - User user = null; - int eventType; + public List parse(InputStream inputStream, ProgressListener progressListener) throws Exception { + init(inputStream); + List result = new ArrayList(); + List musicFolders = null; + User user = null; + int eventType; - String tagName = null; - do { - eventType = nextParseEvent(); - if (eventType == XmlPullParser.START_TAG) { - tagName = getElementName(); - if ("user".equals(tagName)) { - user = new User(); + String tagName = null; + do { + eventType = nextParseEvent(); + if (eventType == XmlPullParser.START_TAG) { + tagName = getElementName(); + if ("user".equals(tagName)) { + user = new User(); - user.setUsername(get("username")); - user.setEmail(get("email")); - for(String role: User.ROLES) { - parseSetting(user, role); - } + user.setUsername(get("username")); + user.setEmail(get("email")); + for(String role: User.ROLES) { + parseSetting(user, role); + } - result.add(user); - } else if ("error".equals(tagName)) { - handleError(); - } - } else if(eventType == XmlPullParser.TEXT) { - if("folder".equals(tagName)) { - String id = getText(); - if(musicFolders == null) { - musicFolders = getMusicFolders(); - } + result.add(user); + } else if ("error".equals(tagName)) { + handleError(); + } + } else if(eventType == XmlPullParser.TEXT) { + if("folder".equals(tagName)) { + String id = getText(); + if(musicFolders == null) { + musicFolders = getMusicFolders(); + } - if(user != null) { - if(user.getMusicFolderSettings() == null) { - for (MusicFolder musicFolder : musicFolders) { - user.addMusicFolder(musicFolder); - } - } + if(user != null) { + if(user.getMusicFolderSettings() == null) { + for (MusicFolder musicFolder : musicFolders) { + user.addMusicFolder(musicFolder); + } + } - for(Setting musicFolder: user.getMusicFolderSettings()) { - if(musicFolder.getName().equals(id)) { - musicFolder.setValue(true); - break; - } - } - } - } - } - } while (eventType != XmlPullParser.END_DOCUMENT); + for(Setting musicFolder: user.getMusicFolderSettings()) { + if(musicFolder.getName().equals(id)) { + musicFolder.setValue(true); + break; + } + } + } + } + } + } while (eventType != XmlPullParser.END_DOCUMENT); - validate(); + validate(); - return result; - } + return result; + } - private List getMusicFolders() throws Exception{ - MusicService musicService = MusicServiceFactory.getMusicService(context); - return musicService.getMusicFolders(false, context, null); - } - - private void parseSetting(User user, String name) { - String value = get(name); - if(value != null) { - user.addSetting(name, "true".equals(value)); - } - } + private List getMusicFolders() throws Exception{ + MusicService musicService = MusicServiceFactory.getMusicService(context); + return musicService.getMusicFolders(false, context, null); + } + + private void parseSetting(User user, String name) { + String value = get(name); + if(value != null) { + user.addSetting(name, "true".equals(value)); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/service/sync/AuthenticatorService.java b/app/src/main/java/net/nullsum/audinaut/service/sync/AuthenticatorService.java index f41ec61..a55601e 100644 --- a/app/src/main/java/net/nullsum/audinaut/service/sync/AuthenticatorService.java +++ b/app/src/main/java/net/nullsum/audinaut/service/sync/AuthenticatorService.java @@ -34,57 +34,57 @@ import android.os.IBinder; */ public class AuthenticatorService extends Service { - private SubsonicAuthenticator authenticator; + private SubsonicAuthenticator authenticator; - @Override - public void onCreate() { - authenticator = new SubsonicAuthenticator(this); - } + @Override + public void onCreate() { + authenticator = new SubsonicAuthenticator(this); + } - @Override - public IBinder onBind(Intent intent) { - return authenticator.getIBinder(); + @Override + public IBinder onBind(Intent intent) { + return authenticator.getIBinder(); - } + } - private class SubsonicAuthenticator extends AbstractAccountAuthenticator { - public SubsonicAuthenticator(Context context) { - super(context); - } + private class SubsonicAuthenticator extends AbstractAccountAuthenticator { + public SubsonicAuthenticator(Context context) { + super(context); + } - @Override - public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { - return null; - } + @Override + public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { + return null; + } - @Override - public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException { - return null; - } + @Override + public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException { + return null; + } - @Override - public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException { - return null; - } + @Override + public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException { + return null; + } - @Override - public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { - return null; - } + @Override + public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { + return null; + } - @Override - public String getAuthTokenLabel(String authTokenType) { - return null; - } + @Override + public String getAuthTokenLabel(String authTokenType) { + return null; + } - @Override - public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { - return null; - } + @Override + public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { + return null; + } - @Override - public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException { - return null; - } - } + @Override + public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException { + return null; + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/updates/Updater.java b/app/src/main/java/net/nullsum/audinaut/updates/Updater.java index 3612220..4e9a8da 100644 --- a/app/src/main/java/net/nullsum/audinaut/updates/Updater.java +++ b/app/src/main/java/net/nullsum/audinaut/updates/Updater.java @@ -32,71 +32,71 @@ import java.util.List; * @author Scott */ public class Updater { - protected String TAG = Updater.class.getSimpleName(); - protected int version; - protected Context context; - - public Updater(int version) { - // 5.2 should show as 520 instead of 52 - if(version < 100) { - version *= 10; - } - this.version = version; - } - - public void checkUpdates(Context context) { - this.context = context; - List updaters = new ArrayList(); - updaters.add(new UpdaterSongPress()); - - SharedPreferences prefs = Util.getPreferences(context); - int lastVersion = prefs.getInt(Constants.LAST_VERSION, 0); - if(lastVersion == 0) { - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt(Constants.LAST_VERSION, version); - editor.apply(); - } - else if(version > lastVersion) { - SharedPreferences.Editor editor = prefs.edit(); - editor.putInt(Constants.LAST_VERSION, version); - editor.apply(); - - Log.i(TAG, "Updating from version " + lastVersion + " to " + version); - for(Updater updater: updaters) { - if(updater.shouldUpdate(lastVersion)) { - new BackgroundUpdate(context, updater).execute(); - } - } - } - } - - public String getName() { - return this.TAG; - } - - private class BackgroundUpdate extends SilentBackgroundTask { - private final Updater updater; + protected String TAG = Updater.class.getSimpleName(); + protected int version; + protected Context context; - public BackgroundUpdate(Context context, Updater updater) { - super(context); - this.updater = updater; - } + public Updater(int version) { + // 5.2 should show as 520 instead of 52 + if(version < 100) { + version *= 10; + } + this.version = version; + } - @Override - protected Void doInBackground() { - try { - updater.update(context); - } catch(Exception e) { - Log.w(TAG, "Failed to run update for " + updater.getName()); - } - return null; - } - } - - public boolean shouldUpdate(int version) { - return this.version > version; - } - public void update(Context context) { - - } + public void checkUpdates(Context context) { + this.context = context; + List updaters = new ArrayList(); + updaters.add(new UpdaterSongPress()); + + SharedPreferences prefs = Util.getPreferences(context); + int lastVersion = prefs.getInt(Constants.LAST_VERSION, 0); + if(lastVersion == 0) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putInt(Constants.LAST_VERSION, version); + editor.apply(); + } + else if(version > lastVersion) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putInt(Constants.LAST_VERSION, version); + editor.apply(); + + Log.i(TAG, "Updating from version " + lastVersion + " to " + version); + for(Updater updater: updaters) { + if(updater.shouldUpdate(lastVersion)) { + new BackgroundUpdate(context, updater).execute(); + } + } + } + } + + public String getName() { + return this.TAG; + } + + private class BackgroundUpdate extends SilentBackgroundTask { + private final Updater updater; + + public BackgroundUpdate(Context context, Updater updater) { + super(context); + this.updater = updater; + } + + @Override + protected Void doInBackground() { + try { + updater.update(context); + } catch(Exception e) { + Log.w(TAG, "Failed to run update for " + updater.getName()); + } + return null; + } + } + + public boolean shouldUpdate(int version) { + return this.version > version; + } + public void update(Context context) { + + } } diff --git a/app/src/main/java/net/nullsum/audinaut/updates/UpdaterSongPress.java b/app/src/main/java/net/nullsum/audinaut/updates/UpdaterSongPress.java index 41093c8..81673c2 100644 --- a/app/src/main/java/net/nullsum/audinaut/updates/UpdaterSongPress.java +++ b/app/src/main/java/net/nullsum/audinaut/updates/UpdaterSongPress.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2016 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2016 (C) Scott Jackson */ package net.nullsum.audinaut.updates; @@ -22,21 +22,21 @@ import net.nullsum.audinaut.util.Constants; import net.nullsum.audinaut.util.Util; public class UpdaterSongPress extends Updater { - public UpdaterSongPress() { - super(521); - TAG = this.getClass().getSimpleName(); - } + public UpdaterSongPress() { + super(521); + TAG = this.getClass().getSimpleName(); + } - @Override - public void update(Context context) { - SharedPreferences prefs = Util.getPreferences(context); - boolean playNowAfter = prefs.getBoolean("playNowAfter", true); + @Override + public void update(Context context) { + SharedPreferences prefs = Util.getPreferences(context); + boolean playNowAfter = prefs.getBoolean("playNowAfter", true); - // Migrate the old preference so behavior stays the same - if(playNowAfter == false) { - SharedPreferences.Editor editor = prefs.edit(); - editor.putString(Constants.PREFERENCES_KEY_SONG_PRESS_ACTION, "single"); - editor.apply(); - } - } + // Migrate the old preference so behavior stays the same + if(playNowAfter == false) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putString(Constants.PREFERENCES_KEY_SONG_PRESS_ACTION, "single"); + editor.apply(); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/BackgroundTask.java b/app/src/main/java/net/nullsum/audinaut/util/BackgroundTask.java index 05eb463..9147581 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/BackgroundTask.java +++ b/app/src/main/java/net/nullsum/audinaut/util/BackgroundTask.java @@ -45,62 +45,62 @@ public abstract class BackgroundTask implements ProgressListener { private static final String TAG = BackgroundTask.class.getSimpleName(); private final Context context; - protected AtomicBoolean cancelled = new AtomicBoolean(false); - protected OnCancelListener cancelListener; - protected Runnable onCompletionListener = null; - protected Task task; + protected AtomicBoolean cancelled = new AtomicBoolean(false); + protected OnCancelListener cancelListener; + protected Runnable onCompletionListener = null; + protected Task task; - private static final int DEFAULT_CONCURRENCY = 8; - private static final Collection threads = Collections.synchronizedCollection(new ArrayList()); - protected static final BlockingQueue queue = new LinkedBlockingQueue(10); - private static Handler handler = null; - static { - try { - handler = new Handler(Looper.getMainLooper()); - } catch(Exception e) { - // Not called from main thread - } - } + private static final int DEFAULT_CONCURRENCY = 8; + private static final Collection threads = Collections.synchronizedCollection(new ArrayList()); + protected static final BlockingQueue queue = new LinkedBlockingQueue(10); + private static Handler handler = null; + static { + try { + handler = new Handler(Looper.getMainLooper()); + } catch(Exception e) { + // Not called from main thread + } + } public BackgroundTask(Context context) { this.context = context; - if(threads.size() < DEFAULT_CONCURRENCY) { - for(int i = threads.size(); i < DEFAULT_CONCURRENCY; i++) { - Thread thread = new Thread(new TaskRunnable(), String.format("BackgroundTask_%d", i)); - threads.add(thread); - thread.start(); - } - } - if(handler == null) { - try { - handler = new Handler(Looper.getMainLooper()); - } catch(Exception e) { - // Not called from main thread - } - } + if(threads.size() < DEFAULT_CONCURRENCY) { + for(int i = threads.size(); i < DEFAULT_CONCURRENCY; i++) { + Thread thread = new Thread(new TaskRunnable(), String.format("BackgroundTask_%d", i)); + threads.add(thread); + thread.start(); + } + } + if(handler == null) { + try { + handler = new Handler(Looper.getMainLooper()); + } catch(Exception e) { + // Not called from main thread + } + } } - public static void stopThreads() { - for(Thread thread: threads) { - thread.interrupt(); - } - threads.clear(); - queue.clear(); - } + public static void stopThreads() { + for(Thread thread: threads) { + thread.interrupt(); + } + threads.clear(); + queue.clear(); + } protected Activity getActivity() { return (context instanceof Activity) ? ((Activity) context) : null; } - protected Context getContext() { - return context; - } + protected Context getContext() { + return context; + } protected Handler getHandler() { return handler; } - public abstract void execute(); + public abstract void execute(); protected abstract T doInBackground() throws Throwable; @@ -108,10 +108,10 @@ public abstract class BackgroundTask implements ProgressListener { protected void error(Throwable error) { Log.w(TAG, "Got exception: " + error, error); - Activity activity = getActivity(); - if(activity != null) { - new ErrorDialog(activity, getErrorMessage(error), true); - } + Activity activity = getActivity(); + if(activity != null) { + new ErrorDialog(activity, getErrorMessage(error), true); + } } protected String getErrorMessage(Throwable error) { @@ -139,33 +139,33 @@ public abstract class BackgroundTask implements ProgressListener { return error.getClass().getSimpleName(); } - public void cancel() { - if(cancelled.compareAndSet(false, true)) { - if(isRunning()) { - if(cancelListener != null) { - cancelListener.onCancel(); - } else { - task.cancel(); - } - } + public void cancel() { + if(cancelled.compareAndSet(false, true)) { + if(isRunning()) { + if(cancelListener != null) { + cancelListener.onCancel(); + } else { + task.cancel(); + } + } - task = null; - } - } - public boolean isCancelled() { - return cancelled.get(); - } - public void setOnCancelListener(OnCancelListener listener) { - cancelListener = listener; - } + task = null; + } + } + public boolean isCancelled() { + return cancelled.get(); + } + public void setOnCancelListener(OnCancelListener listener) { + cancelListener = listener; + } - public boolean isRunning() { - if(task == null) { - return false; - } else { - return task.isRunning(); - } - } + public boolean isRunning() { + if(task == null) { + return false; + } else { + return task.isRunning(); + } + } @Override public abstract void updateProgress(final String message); @@ -175,151 +175,151 @@ public abstract class BackgroundTask implements ProgressListener { updateProgress(context.getResources().getString(messageId)); } - @Override - public void updateCache(int changeCode) { + @Override + public void updateCache(int changeCode) { - } + } - public void setOnCompletionListener(Runnable onCompletionListener) { - this.onCompletionListener = onCompletionListener; - } + public void setOnCompletionListener(Runnable onCompletionListener) { + this.onCompletionListener = onCompletionListener; + } - protected class Task { - private Thread thread; - private AtomicBoolean taskStart = new AtomicBoolean(false); + protected class Task { + private Thread thread; + private AtomicBoolean taskStart = new AtomicBoolean(false); - private void execute() throws Exception { - // Don't run if cancelled already - if(isCancelled()) { - return; - } + private void execute() throws Exception { + // Don't run if cancelled already + if(isCancelled()) { + return; + } - try { - thread = Thread.currentThread(); - taskStart.set(true); + try { + thread = Thread.currentThread(); + taskStart.set(true); - final T result = doInBackground(); - if(isCancelled()) { - taskStart.set(false); - return; - } + final T result = doInBackground(); + if(isCancelled()) { + taskStart.set(false); + return; + } - if(handler != null) { - handler.post(new Runnable() { - @Override - public void run() { - if (!isCancelled()) { - try { - onDone(result); - } catch (Throwable t) { - if(!isCancelled()) { - try { - onError(t); - } catch(Exception e) { - // Don't care - } - } - } - } + if(handler != null) { + handler.post(new Runnable() { + @Override + public void run() { + if (!isCancelled()) { + try { + onDone(result); + } catch (Throwable t) { + if(!isCancelled()) { + try { + onError(t); + } catch(Exception e) { + // Don't care + } + } + } + } - taskStart.set(false); - } - }); - } else { - taskStart.set(false); - } - } catch(InterruptedException interrupt) { - if(taskStart.get()) { - // Don't exit root thread if task cancelled - throw interrupt; - } - } catch(final Throwable t) { - if(isCancelled()) { - taskStart.set(false); - return; - } + taskStart.set(false); + } + }); + } else { + taskStart.set(false); + } + } catch(InterruptedException interrupt) { + if(taskStart.get()) { + // Don't exit root thread if task cancelled + throw interrupt; + } + } catch(final Throwable t) { + if(isCancelled()) { + taskStart.set(false); + return; + } - if(handler != null) { - handler.post(new Runnable() { - @Override - public void run() { - if(!isCancelled()) { - try { - onError(t); - } catch(Exception e) { - // Don't care - } - } + if(handler != null) { + handler.post(new Runnable() { + @Override + public void run() { + if(!isCancelled()) { + try { + onError(t); + } catch(Exception e) { + // Don't care + } + } - taskStart.set(false); - } - }); - } else { - taskStart.set(false); - } - } finally { - thread = null; - } - } + taskStart.set(false); + } + }); + } else { + taskStart.set(false); + } + } finally { + thread = null; + } + } - public void cancel() { - if(taskStart.compareAndSet(true, false)) { - if (thread != null) { - thread.interrupt(); - } - } - } - public boolean isCancelled() { - if(Thread.interrupted()) { - return true; - } else if(BackgroundTask.this.isCancelled()) { - return true; - } else { - return false; - } - } - public void onDone(T result) { - done(result); + public void cancel() { + if(taskStart.compareAndSet(true, false)) { + if (thread != null) { + thread.interrupt(); + } + } + } + public boolean isCancelled() { + if(Thread.interrupted()) { + return true; + } else if(BackgroundTask.this.isCancelled()) { + return true; + } else { + return false; + } + } + public void onDone(T result) { + done(result); - if(onCompletionListener != null) { - onCompletionListener.run(); - } - } - public void onError(Throwable t) { - error(t); - } + if(onCompletionListener != null) { + onCompletionListener.run(); + } + } + public void onError(Throwable t) { + error(t); + } - public boolean isRunning() { - return taskStart.get(); - } - } + public boolean isRunning() { + return taskStart.get(); + } + } - private class TaskRunnable implements Runnable { - private boolean running = true; + private class TaskRunnable implements Runnable { + private boolean running = true; - public TaskRunnable() { + public TaskRunnable() { - } + } - @Override - public void run() { - Looper.prepare(); - while(running) { - try { - Task task = queue.take(); - task.execute(); - } catch(InterruptedException stop) { - Log.e(TAG, "Thread died"); - running = false; - threads.remove(Thread.currentThread()); - } catch(Throwable t) { - Log.e(TAG, "Unexpected crash in BackgroundTask thread", t); - } - } - } - } + @Override + public void run() { + Looper.prepare(); + while(running) { + try { + Task task = queue.take(); + task.execute(); + } catch(InterruptedException stop) { + Log.e(TAG, "Thread died"); + running = false; + threads.remove(Thread.currentThread()); + } catch(Throwable t) { + Log.e(TAG, "Unexpected crash in BackgroundTask thread", t); + } + } + } + } - public static interface OnCancelListener { - void onCancel(); - } + public static interface OnCancelListener { + void onCancel(); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/BufferFile.java b/app/src/main/java/net/nullsum/audinaut/util/BufferFile.java index 4b0f93f..ac18403 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/BufferFile.java +++ b/app/src/main/java/net/nullsum/audinaut/util/BufferFile.java @@ -1,16 +1,16 @@ /* - This file is part of ServerProxy. - SocketProxy 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + This file is part of ServerProxy. + SocketProxy 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.util; @@ -18,11 +18,11 @@ package net.nullsum.audinaut.util; import java.io.File; public interface BufferFile { - File getFile(); - Long getContentLength(); - long getEstimatedSize(); - boolean isWorkDone(); - void onStart(); - void onStop(); - void onResume(); + File getFile(); + Long getContentLength(); + long getEstimatedSize(); + boolean isWorkDone(); + void onStart(); + void onStop(); + void onResume(); } diff --git a/app/src/main/java/net/nullsum/audinaut/util/BufferProxy.java b/app/src/main/java/net/nullsum/audinaut/util/BufferProxy.java index b4e947c..907a0b5 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/BufferProxy.java +++ b/app/src/main/java/net/nullsum/audinaut/util/BufferProxy.java @@ -23,60 +23,60 @@ import android.content.Context; import net.nullsum.audinaut.util.FileProxy; public class BufferProxy extends FileProxy { - private static final String TAG = BufferProxy.class.getSimpleName(); - protected BufferFile progress; + private static final String TAG = BufferProxy.class.getSimpleName(); + protected BufferFile progress; - public BufferProxy(Context context) { - super(context); - } + public BufferProxy(Context context) { + super(context); + } - protected ProxyTask getTask(Socket client) { - return new BufferFileTask(client); - } + protected ProxyTask getTask(Socket client) { + return new BufferFileTask(client); + } - public void setBufferFile(BufferFile progress) { - this.progress = progress; - } + public void setBufferFile(BufferFile progress) { + this.progress = progress; + } - protected class BufferFileTask extends StreamFileTask { - public BufferFileTask(Socket client) { - super(client); - } + protected class BufferFileTask extends StreamFileTask { + public BufferFileTask(Socket client) { + super(client); + } - @Override - File getFile(String path) { - return progress.getFile(); - } + @Override + File getFile(String path) { + return progress.getFile(); + } - @Override - Long getContentLength() { - Long contentLength = progress.getContentLength(); - if(contentLength == null && progress.isWorkDone()) { - contentLength = file.length(); - } - return contentLength; - } - @Override - long getFileSize() { - return progress.getEstimatedSize(); - } + @Override + Long getContentLength() { + Long contentLength = progress.getContentLength(); + if(contentLength == null && progress.isWorkDone()) { + contentLength = file.length(); + } + return contentLength; + } + @Override + long getFileSize() { + return progress.getEstimatedSize(); + } - @Override - public void onStart() { - progress.onStart(); - } - @Override - public void onStop() { - progress.onStop(); - } - @Override - public void onResume() { - progress.onResume(); - } + @Override + public void onStart() { + progress.onStart(); + } + @Override + public void onStop() { + progress.onStop(); + } + @Override + public void onResume() { + progress.onResume(); + } - @Override - public boolean isWorkDone() { - return progress.isWorkDone() && cbSkip >= file.length(); - } - } + @Override + public boolean isWorkDone() { + return progress.isWorkDone() && cbSkip >= file.length(); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/CacheCleaner.java b/app/src/main/java/net/nullsum/audinaut/util/CacheCleaner.java index c9e9221..b275c68 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/CacheCleaner.java +++ b/app/src/main/java/net/nullsum/audinaut/util/CacheCleaner.java @@ -25,28 +25,28 @@ import java.util.*; public class CacheCleaner { private static final String TAG = CacheCleaner.class.getSimpleName(); - private static final long MIN_FREE_SPACE = 500 * 1024L * 1024L; - private static final long MAX_COVER_ART_SPACE = 100 * 1024L * 1024L; + private static final long MIN_FREE_SPACE = 500 * 1024L * 1024L; + private static final long MAX_COVER_ART_SPACE = 100 * 1024L * 1024L; private final Context context; private final DownloadService downloadService; - private final MediaStoreService mediaStore; + private final MediaStoreService mediaStore; public CacheCleaner(Context context, DownloadService downloadService) { this.context = context; this.downloadService = downloadService; - this.mediaStore = new MediaStoreService(context); + this.mediaStore = new MediaStoreService(context); } public void clean() { - new BackgroundCleanup(context).execute(); + new BackgroundCleanup(context).execute(); + } + public void cleanSpace() { + new BackgroundSpaceCleanup(context).execute(); + } + public void cleanPlaylists(List playlists) { + new BackgroundPlaylistsCleanup(context, playlists).execute(); } - public void cleanSpace() { - new BackgroundSpaceCleanup(context).execute(); - } - public void cleanPlaylists(List playlists) { - new BackgroundPlaylistsCleanup(context, playlists).execute(); - } private void deleteEmptyDirs(List dirs, Set undeletable) { for (File dir : dirs) { @@ -57,14 +57,14 @@ public class CacheCleaner { FileUtil.deleteEmptyDir(dir); } } - - private long getMinimumDelete(List files, List pinned) { - if(files.size() == 0) { - return 0L; - } - - long cacheSizeBytes = Util.getCacheSizeMB(context) * 1024L * 1024L; - + + private long getMinimumDelete(List files, List pinned) { + if(files.size() == 0) { + return 0L; + } + + long cacheSizeBytes = Util.getCacheSizeMB(context) * 1024L * 1024L; + long bytesUsedBySubsonic = 0L; for (File file : files) { bytesUsedBySubsonic += file.length(); @@ -72,8 +72,8 @@ public class CacheCleaner { for (File file : pinned) { bytesUsedBySubsonic += file.length(); } - - // Ensure that file system is not more than 95% full. + + // Ensure that file system is not more than 95% full. StatFs stat = new StatFs(files.get(0).getPath()); long bytesTotalFs = (long) stat.getBlockCount() * (long) stat.getBlockSize(); long bytesAvailableFs = (long) stat.getAvailableBlocks() * (long) stat.getBlockSize(); @@ -88,9 +88,9 @@ public class CacheCleaner { Log.i(TAG, "Cache limit : " + Util.formatBytes(cacheSizeBytes)); Log.i(TAG, "Cache size before : " + Util.formatBytes(bytesUsedBySubsonic)); Log.i(TAG, "Minimum to delete : " + Util.formatBytes(bytesToDelete)); - - return bytesToDelete; - } + + return bytesToDelete; + } private void deleteFiles(List files, Set undeletable, long bytesToDelete, boolean deletePartials) { if (files.isEmpty()) { @@ -99,14 +99,14 @@ public class CacheCleaner { long bytesDeleted = 0L; for (File file : files) { - if(!deletePartials && bytesDeleted > bytesToDelete) break; + if(!deletePartials && bytesDeleted > bytesToDelete) break; if (bytesToDelete > bytesDeleted || (deletePartials && (file.getName().endsWith(".partial") || file.getName().contains(".partial.")))) { if (!undeletable.contains(file) && !file.getName().equals(Constants.ALBUM_ART_FILE)) { long size = file.length(); if (Util.delete(file)) { bytesDeleted += size; - mediaStore.deleteFromMediaStore(file); + mediaStore.deleteFromMediaStore(file); } } } @@ -122,8 +122,8 @@ public class CacheCleaner { if (isCacheFile) { files.add(file); } else { - pinned.add(file); - } + pinned.add(file); + } } else { // Depth-first for (File child : FileUtil.listFiles(file)) { @@ -159,134 +159,134 @@ public class CacheCleaner { undeletable.add(FileUtil.getMusicDirectory(context)); return undeletable; } - - private void cleanupCoverArt(Context context) { - File dir = FileUtil.getAlbumArtDirectory(context); - - List files = new ArrayList(); - long bytesUsed = 0L; - for(File file: dir.listFiles()) { - if(file.isFile()) { - files.add(file); - bytesUsed += file.length(); - } - } - - // Don't waste time sorting if under limit already - if(bytesUsed < MAX_COVER_ART_SPACE) { - return; - } - - sortByAscendingModificationTime(files); - long bytesDeleted = 0L; - for(File file: files) { - // End as soon as the space used is below the threshold - if(bytesUsed < MAX_COVER_ART_SPACE) { - break; - } - - long bytes = file.length(); - if(file.delete()) { - bytesUsed -= bytes; - bytesDeleted += bytes; - } - } - - Log.i(TAG, "Deleted " + Util.formatBytes(bytesDeleted) + " worth of cover art"); - } - - private class BackgroundCleanup extends SilentBackgroundTask { - public BackgroundCleanup(Context context) { - super(context); - } - @Override - protected Void doInBackground() { - if (downloadService == null) { - Log.e(TAG, "DownloadService not set. Aborting cache cleaning."); - return null; - } + private void cleanupCoverArt(Context context) { + File dir = FileUtil.getAlbumArtDirectory(context); - try { - List files = new ArrayList(); - List pinned = new ArrayList(); - List dirs = new ArrayList(); + List files = new ArrayList(); + long bytesUsed = 0L; + for(File file: dir.listFiles()) { + if(file.isFile()) { + files.add(file); + bytesUsed += file.length(); + } + } - findCandidatesForDeletion(FileUtil.getMusicDirectory(context), files, pinned, dirs); - sortByAscendingModificationTime(files); + // Don't waste time sorting if under limit already + if(bytesUsed < MAX_COVER_ART_SPACE) { + return; + } - Set undeletable = findUndeletableFiles(); + sortByAscendingModificationTime(files); + long bytesDeleted = 0L; + for(File file: files) { + // End as soon as the space used is below the threshold + if(bytesUsed < MAX_COVER_ART_SPACE) { + break; + } - deleteFiles(files, undeletable, getMinimumDelete(files, pinned), true); - deleteEmptyDirs(dirs, undeletable); - - // Make sure cover art directory does not grow too large - cleanupCoverArt(context); - } catch (RuntimeException x) { - Log.e(TAG, "Error in cache cleaning.", x); - } + long bytes = file.length(); + if(file.delete()) { + bytesUsed -= bytes; + bytesDeleted += bytes; + } + } - return null; - } - } + Log.i(TAG, "Deleted " + Util.formatBytes(bytesDeleted) + " worth of cover art"); + } - private class BackgroundSpaceCleanup extends SilentBackgroundTask { - public BackgroundSpaceCleanup(Context context) { - super(context); - } + private class BackgroundCleanup extends SilentBackgroundTask { + public BackgroundCleanup(Context context) { + super(context); + } - @Override - protected Void doInBackground() { - if (downloadService == null) { - Log.e(TAG, "DownloadService not set. Aborting cache cleaning."); - return null; - } + @Override + protected Void doInBackground() { + if (downloadService == null) { + Log.e(TAG, "DownloadService not set. Aborting cache cleaning."); + return null; + } - try { - List files = new ArrayList(); - List pinned = new ArrayList(); - List dirs = new ArrayList(); - findCandidatesForDeletion(FileUtil.getMusicDirectory(context), files, pinned, dirs); + try { + List files = new ArrayList(); + List pinned = new ArrayList(); + List dirs = new ArrayList(); - long bytesToDelete = getMinimumDelete(files, pinned); - if(bytesToDelete > 0L) { - sortByAscendingModificationTime(files); - Set undeletable = findUndeletableFiles(); - deleteFiles(files, undeletable, bytesToDelete, false); - } - } catch (RuntimeException x) { - Log.e(TAG, "Error in cache cleaning.", x); - } + findCandidatesForDeletion(FileUtil.getMusicDirectory(context), files, pinned, dirs); + sortByAscendingModificationTime(files); - return null; - } - } + Set undeletable = findUndeletableFiles(); - private class BackgroundPlaylistsCleanup extends SilentBackgroundTask { - private final List playlists; + deleteFiles(files, undeletable, getMinimumDelete(files, pinned), true); + deleteEmptyDirs(dirs, undeletable); - public BackgroundPlaylistsCleanup(Context context, List playlists) { - super(context); - this.playlists = playlists; - } + // Make sure cover art directory does not grow too large + cleanupCoverArt(context); + } catch (RuntimeException x) { + Log.e(TAG, "Error in cache cleaning.", x); + } - @Override - protected Void doInBackground() { - try { - String server = Util.getServerName(context); - SortedSet playlistFiles = FileUtil.listFiles(FileUtil.getPlaylistDirectory(context, server)); - for (Playlist playlist : playlists) { - playlistFiles.remove(FileUtil.getPlaylistFile(context, server, playlist.getName())); - } + return null; + } + } - for(File playlist : playlistFiles) { - playlist.delete(); - } - } catch (RuntimeException x) { - Log.e(TAG, "Error in playlist cache cleaning.", x); - } + private class BackgroundSpaceCleanup extends SilentBackgroundTask { + public BackgroundSpaceCleanup(Context context) { + super(context); + } - return null; - } - } + @Override + protected Void doInBackground() { + if (downloadService == null) { + Log.e(TAG, "DownloadService not set. Aborting cache cleaning."); + return null; + } + + try { + List files = new ArrayList(); + List pinned = new ArrayList(); + List dirs = new ArrayList(); + findCandidatesForDeletion(FileUtil.getMusicDirectory(context), files, pinned, dirs); + + long bytesToDelete = getMinimumDelete(files, pinned); + if(bytesToDelete > 0L) { + sortByAscendingModificationTime(files); + Set undeletable = findUndeletableFiles(); + deleteFiles(files, undeletable, bytesToDelete, false); + } + } catch (RuntimeException x) { + Log.e(TAG, "Error in cache cleaning.", x); + } + + return null; + } + } + + private class BackgroundPlaylistsCleanup extends SilentBackgroundTask { + private final List playlists; + + public BackgroundPlaylistsCleanup(Context context, List playlists) { + super(context); + this.playlists = playlists; + } + + @Override + protected Void doInBackground() { + try { + String server = Util.getServerName(context); + SortedSet playlistFiles = FileUtil.listFiles(FileUtil.getPlaylistDirectory(context, server)); + for (Playlist playlist : playlists) { + playlistFiles.remove(FileUtil.getPlaylistFile(context, server, playlist.getName())); + } + + for(File playlist : playlistFiles) { + playlist.delete(); + } + } catch (RuntimeException x) { + Log.e(TAG, "Error in playlist cache cleaning.", x); + } + + return null; + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/Constants.java b/app/src/main/java/net/nullsum/audinaut/util/Constants.java index 96206e4..283dc5a 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/Constants.java +++ b/app/src/main/java/net/nullsum/audinaut/util/Constants.java @@ -29,13 +29,13 @@ public final class Constants { public static final String REST_PROTOCOL_VERSION_SUBSONIC = "1.13.0"; public static final String REST_CLIENT_ID = "Audinaut"; - public static final String LAST_VERSION = "subsonic.version"; + public static final String LAST_VERSION = "subsonic.version"; // Names for intent extras. public static final String INTENT_EXTRA_NAME_ID = "subsonic.id"; public static final String INTENT_EXTRA_NAME_NAME = "subsonic.name"; - public static final String INTENT_EXTRA_NAME_DIRECTORY = "subsonic.directory"; - public static final String INTENT_EXTRA_NAME_CHILD_ID = "subsonic.child.id"; + public static final String INTENT_EXTRA_NAME_DIRECTORY = "subsonic.directory"; + public static final String INTENT_EXTRA_NAME_CHILD_ID = "subsonic.child.id"; public static final String INTENT_EXTRA_NAME_ARTIST = "subsonic.artist"; public static final String INTENT_EXTRA_NAME_TITLE = "subsonic.title"; public static final String INTENT_EXTRA_NAME_AUTOPLAY = "subsonic.playall"; @@ -44,131 +44,131 @@ public final class Constants { public static final String INTENT_EXTRA_NAME_PLAYLIST_NAME = "subsonic.playlist.name"; public static final String INTENT_EXTRA_NAME_PLAYLIST_OWNER = "subsonic.playlist.isOwner"; public static final String INTENT_EXTRA_NAME_ALBUM_LIST_TYPE = "subsonic.albumlisttype"; - public static final String INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA = "subsonic.albumlistextra"; + public static final String INTENT_EXTRA_NAME_ALBUM_LIST_EXTRA = "subsonic.albumlistextra"; public static final String INTENT_EXTRA_NAME_ALBUM_LIST_SIZE = "subsonic.albumlistsize"; public static final String INTENT_EXTRA_NAME_ALBUM_LIST_OFFSET = "subsonic.albumlistoffset"; public static final String INTENT_EXTRA_NAME_SHUFFLE = "subsonic.shuffle"; public static final String INTENT_EXTRA_REQUEST_SEARCH = "subsonic.requestsearch"; public static final String INTENT_EXTRA_NAME_EXIT = "subsonic.exit" ; - public static final String INTENT_EXTRA_NAME_DOWNLOAD = "subsonic.download"; - public static final String INTENT_EXTRA_NAME_DOWNLOAD_VIEW = "subsonic.download_view"; - public static final String INTENT_EXTRA_VIEW_ALBUM = "subsonic.view_album"; - public static final String INTENT_EXTRA_NAME_SHARE = "subsonic.share"; - public static final String INTENT_EXTRA_FRAGMENT_TYPE = "fragmentType"; - public static final String INTENT_EXTRA_REFRESH_LISTINGS = "refreshListings"; - public static final String INTENT_EXTRA_SEARCH_SONG = "searchSong"; - public static final String INTENT_EXTRA_TOP_TRACKS = "topTracks"; - public static final String INTENT_EXTRA_PLAY_LAST = "playLast"; - public static final String INTENT_EXTRA_ENTRY = "passedEntry"; + public static final String INTENT_EXTRA_NAME_DOWNLOAD = "subsonic.download"; + public static final String INTENT_EXTRA_NAME_DOWNLOAD_VIEW = "subsonic.download_view"; + public static final String INTENT_EXTRA_VIEW_ALBUM = "subsonic.view_album"; + public static final String INTENT_EXTRA_NAME_SHARE = "subsonic.share"; + public static final String INTENT_EXTRA_FRAGMENT_TYPE = "fragmentType"; + public static final String INTENT_EXTRA_REFRESH_LISTINGS = "refreshListings"; + public static final String INTENT_EXTRA_SEARCH_SONG = "searchSong"; + public static final String INTENT_EXTRA_TOP_TRACKS = "topTracks"; + public static final String INTENT_EXTRA_PLAY_LAST = "playLast"; + public static final String INTENT_EXTRA_ENTRY = "passedEntry"; // Preferences keys. - public static final String PREFERENCES_KEY_SERVER_KEY = "server"; - public static final String PREFERENCES_KEY_SERVER_COUNT = "serverCount"; - public static final String PREFERENCES_KEY_SERVER_ADD = "serverAdd"; - public static final String PREFERENCES_KEY_SERVER_REMOVE = "serverRemove"; + public static final String PREFERENCES_KEY_SERVER_KEY = "server"; + public static final String PREFERENCES_KEY_SERVER_COUNT = "serverCount"; + public static final String PREFERENCES_KEY_SERVER_ADD = "serverAdd"; + public static final String PREFERENCES_KEY_SERVER_REMOVE = "serverRemove"; public static final String PREFERENCES_KEY_SERVER_INSTANCE = "serverInstanceId"; public static final String PREFERENCES_KEY_SERVER_NAME = "serverName"; public static final String PREFERENCES_KEY_SERVER_URL = "serverUrl"; - public static final String PREFERENCES_KEY_SERVER_INTERNAL_URL = "serverInternalUrl"; - public static final String PREFERENCES_KEY_SERVER_LOCAL_NETWORK_SSID = "serverLocalNetworkSSID"; - public static final String PREFERENCES_KEY_TEST_CONNECTION = "serverTestConnection"; - public static final String PREFERENCES_KEY_OPEN_BROWSER = "openBrowser"; + public static final String PREFERENCES_KEY_SERVER_INTERNAL_URL = "serverInternalUrl"; + public static final String PREFERENCES_KEY_SERVER_LOCAL_NETWORK_SSID = "serverLocalNetworkSSID"; + public static final String PREFERENCES_KEY_TEST_CONNECTION = "serverTestConnection"; + public static final String PREFERENCES_KEY_OPEN_BROWSER = "openBrowser"; public static final String PREFERENCES_KEY_MUSIC_FOLDER_ID = "musicFolderId"; public static final String PREFERENCES_KEY_USERNAME = "username"; public static final String PREFERENCES_KEY_PASSWORD = "password"; public static final String PREFERENCES_KEY_INSTALL_TIME = "installTime"; public static final String PREFERENCES_KEY_THEME = "theme"; public static final String PREFERENCES_KEY_FULL_SCREEN = "fullScreen"; - public static final String PREFERENCES_KEY_DISPLAY_TRACK = "displayTrack"; + public static final String PREFERENCES_KEY_DISPLAY_TRACK = "displayTrack"; public static final String PREFERENCES_KEY_MAX_BITRATE_WIFI = "maxBitrateWifi"; public static final String PREFERENCES_KEY_MAX_BITRATE_MOBILE = "maxBitrateMobile"; - public static final String PREFERENCES_KEY_NETWORK_TIMEOUT = "networkTimeout"; + public static final String PREFERENCES_KEY_NETWORK_TIMEOUT = "networkTimeout"; public static final String PREFERENCES_KEY_CACHE_SIZE = "cacheSize"; public static final String PREFERENCES_KEY_CACHE_LOCATION = "cacheLocation"; public static final String PREFERENCES_KEY_PRELOAD_COUNT_WIFI = "preloadCountWifi"; - public static final String PREFERENCES_KEY_PRELOAD_COUNT_MOBILE = "preloadCountMobile"; + public static final String PREFERENCES_KEY_PRELOAD_COUNT_MOBILE = "preloadCountMobile"; public static final String PREFERENCES_KEY_HIDE_MEDIA = "hideMedia"; public static final String PREFERENCES_KEY_MEDIA_BUTTONS = "mediaButtons"; public static final String PREFERENCES_KEY_SCREEN_LIT_ON_DOWNLOAD = "screenLitOnDownload"; public static final String PREFERENCES_KEY_REPEAT_MODE = "repeatMode"; public static final String PREFERENCES_KEY_WIFI_REQUIRED_FOR_DOWNLOAD = "wifiRequiredForDownload"; - public static final String PREFERENCES_KEY_RANDOM_SIZE = "randomSize"; - public static final String PREFERENCES_KEY_OFFLINE = "offline"; - public static final String PREFERENCES_KEY_TEMP_LOSS = "tempLoss"; - public static final String PREFERENCES_KEY_SHUFFLE_START_YEAR = "startYear"; - public static final String PREFERENCES_KEY_SHUFFLE_END_YEAR = "endYear"; - public static final String PREFERENCES_KEY_SHUFFLE_GENRE = "genre"; - public static final String PREFERENCES_KEY_KEEP_SCREEN_ON = "keepScreenOn"; - public static final String PREFERENCES_EQUALIZER_ON = "equalizerOn"; - public static final String PREFERENCES_EQUALIZER_SETTINGS = "equalizerSettings"; - public static final String PREFERENCES_KEY_PERSISTENT_NOTIFICATION = "persistentNotification"; - public static final String PREFERENCES_KEY_GAPLESS_PLAYBACK = "gaplessPlayback"; - public static final String PREFERENCES_KEY_REMOVE_PLAYED = "removePlayed"; - public static final String PREFERENCES_KEY_KEEP_PLAYED_CNT = "keepPlayedCount"; - public static final String PREFERENCES_KEY_SHUFFLE_MODE = "shuffleMode2"; - public static final String PREFERENCES_KEY_SHUFFLE_MODE_EXTRA = "shuffleModeExtra"; - public static final String PREFERENCES_KEY_SYNC_ENABLED = "syncEnabled"; - public static final String PREFERENCES_KEY_SYNC_INTERVAL = "syncInterval"; - public static final String PREFERENCES_KEY_SYNC_WIFI = "syncWifi"; - public static final String PREFERENCES_KEY_SYNC_NOTIFICATION = "syncNotification"; - public static final String PREFERENCES_KEY_SYNC_MOST_RECENT = "syncMostRecent"; - public static final String PREFERENCES_KEY_PAUSE_DISCONNECT = "pauseOnDisconnect"; - public static final String PREFERENCES_KEY_HIDE_WIDGET = "hideWidget"; - public static final String PREFERENCES_KEY_CUSTOM_SORT_ENABLED = "customSortEnabled"; - public static final String PREFERENCES_KEY_SHARED_ENABLED = "sharedEnabled"; - public static final String PREFERENCES_KEY_OPEN_TO_TAB = "openToTab"; - // public static final String PREFERENCES_KEY_PLAY_NOW_AFTER = "playNowAfter"; - public static final String PREFERENCES_KEY_SONG_PRESS_ACTION = "songPressAction"; - public static final String PREFERENCES_KEY_LARGE_ALBUM_ART = "largeAlbumArt"; - public static final String PREFERENCES_KEY_PLAYLIST_NAME = "suggestedPlaylistName"; - public static final String PREFERENCES_KEY_PLAYLIST_ID = "suggestedPlaylistId"; - public static final String PREFERENCES_KEY_RECENT_COUNT = "mostRecentCount"; - public static final String PREFERENCES_KEY_REPLAY_GAIN = "replayGain"; - public static final String PREFERENCES_KEY_REPLAY_GAIN_BUMP = "replayGainBump2"; - public static final String PREFERENCES_KEY_REPLAY_GAIN_UNTAGGED = "replayGainUntagged2"; - public static final String PREFERENCES_KEY_REPLAY_GAIN_TYPE= "replayGainType"; - public static final String PREFERENCES_KEY_ALBUMS_PER_FOLDER = "albumsPerFolder"; - public static final String PREFERENCES_KEY_FIRST_LEVEL_ARTIST = "firstLevelArtist"; - public static final String PREFERENCES_KEY_START_ON_HEADPHONES = "startOnHeadphones"; - public static final String PREFERENCES_KEY_COLOR_ACTION_BAR = "colorActionBar"; - public static final String PREFERENCES_KEY_SHUFFLE_BY_ALBUM = "shuffleByAlbum"; - public static final String PREFERENCES_KEY_RESUME_PLAY_QUEUE_NEVER = "neverResumePlayQueue"; - public static final String PREFERENCES_KEY_BATCH_MODE = "batchMode"; - public static final String PREFERENCES_KEY_HEADS_UP_NOTIFICATION = "headsUpNotification"; - - public static final String OFFLINE_STAR_COUNT = "starCount"; - public static final String OFFLINE_STAR_ID = "starID"; - public static final String OFFLINE_STAR_SEARCH = "starTitle"; - public static final String OFFLINE_STAR_SETTING = "starSetting"; - - public static final String CACHE_KEY_IGNORE = "ignoreArticles"; - public static final String CACHE_AUDIO_SESSION_ID = "audioSessionId"; - public static final String CACHE_BLOCK_TOKEN_USE = "blockTokenUse"; - - public static final String MAIN_BACK_STACK = "backStackIds"; - public static final String MAIN_BACK_STACK_SIZE = "backStackIdsSize"; - public static final String MAIN_NOW_PLAYING = "nowPlayingId"; - public static final String MAIN_NOW_PLAYING_SECONDARY = "nowPlayingSecondaryId"; - public static final String MAIN_SLIDE_PANEL_STATE = "slidePanelState"; - public static final String FRAGMENT_LIST = "fragmentList"; - public static final String FRAGMENT_LIST2 = "fragmentList2"; - public static final String FRAGMENT_EXTRA = "fragmentExtra"; - public static final String FRAGMENT_DOWNLOAD_FLIPPER = "fragmentDownloadFlipper"; - public static final String FRAGMENT_NAME = "fragmentName"; - public static final String FRAGMENT_POSITION = "fragmentPosition"; + public static final String PREFERENCES_KEY_RANDOM_SIZE = "randomSize"; + public static final String PREFERENCES_KEY_OFFLINE = "offline"; + public static final String PREFERENCES_KEY_TEMP_LOSS = "tempLoss"; + public static final String PREFERENCES_KEY_SHUFFLE_START_YEAR = "startYear"; + public static final String PREFERENCES_KEY_SHUFFLE_END_YEAR = "endYear"; + public static final String PREFERENCES_KEY_SHUFFLE_GENRE = "genre"; + public static final String PREFERENCES_KEY_KEEP_SCREEN_ON = "keepScreenOn"; + public static final String PREFERENCES_EQUALIZER_ON = "equalizerOn"; + public static final String PREFERENCES_EQUALIZER_SETTINGS = "equalizerSettings"; + public static final String PREFERENCES_KEY_PERSISTENT_NOTIFICATION = "persistentNotification"; + public static final String PREFERENCES_KEY_GAPLESS_PLAYBACK = "gaplessPlayback"; + public static final String PREFERENCES_KEY_REMOVE_PLAYED = "removePlayed"; + public static final String PREFERENCES_KEY_KEEP_PLAYED_CNT = "keepPlayedCount"; + public static final String PREFERENCES_KEY_SHUFFLE_MODE = "shuffleMode2"; + public static final String PREFERENCES_KEY_SHUFFLE_MODE_EXTRA = "shuffleModeExtra"; + public static final String PREFERENCES_KEY_SYNC_ENABLED = "syncEnabled"; + public static final String PREFERENCES_KEY_SYNC_INTERVAL = "syncInterval"; + public static final String PREFERENCES_KEY_SYNC_WIFI = "syncWifi"; + public static final String PREFERENCES_KEY_SYNC_NOTIFICATION = "syncNotification"; + public static final String PREFERENCES_KEY_SYNC_MOST_RECENT = "syncMostRecent"; + public static final String PREFERENCES_KEY_PAUSE_DISCONNECT = "pauseOnDisconnect"; + public static final String PREFERENCES_KEY_HIDE_WIDGET = "hideWidget"; + public static final String PREFERENCES_KEY_CUSTOM_SORT_ENABLED = "customSortEnabled"; + public static final String PREFERENCES_KEY_SHARED_ENABLED = "sharedEnabled"; + public static final String PREFERENCES_KEY_OPEN_TO_TAB = "openToTab"; + // public static final String PREFERENCES_KEY_PLAY_NOW_AFTER = "playNowAfter"; + public static final String PREFERENCES_KEY_SONG_PRESS_ACTION = "songPressAction"; + public static final String PREFERENCES_KEY_LARGE_ALBUM_ART = "largeAlbumArt"; + public static final String PREFERENCES_KEY_PLAYLIST_NAME = "suggestedPlaylistName"; + public static final String PREFERENCES_KEY_PLAYLIST_ID = "suggestedPlaylistId"; + public static final String PREFERENCES_KEY_RECENT_COUNT = "mostRecentCount"; + public static final String PREFERENCES_KEY_REPLAY_GAIN = "replayGain"; + public static final String PREFERENCES_KEY_REPLAY_GAIN_BUMP = "replayGainBump2"; + public static final String PREFERENCES_KEY_REPLAY_GAIN_UNTAGGED = "replayGainUntagged2"; + public static final String PREFERENCES_KEY_REPLAY_GAIN_TYPE= "replayGainType"; + public static final String PREFERENCES_KEY_ALBUMS_PER_FOLDER = "albumsPerFolder"; + public static final String PREFERENCES_KEY_FIRST_LEVEL_ARTIST = "firstLevelArtist"; + public static final String PREFERENCES_KEY_START_ON_HEADPHONES = "startOnHeadphones"; + public static final String PREFERENCES_KEY_COLOR_ACTION_BAR = "colorActionBar"; + public static final String PREFERENCES_KEY_SHUFFLE_BY_ALBUM = "shuffleByAlbum"; + public static final String PREFERENCES_KEY_RESUME_PLAY_QUEUE_NEVER = "neverResumePlayQueue"; + public static final String PREFERENCES_KEY_BATCH_MODE = "batchMode"; + public static final String PREFERENCES_KEY_HEADS_UP_NOTIFICATION = "headsUpNotification"; + + public static final String OFFLINE_STAR_COUNT = "starCount"; + public static final String OFFLINE_STAR_ID = "starID"; + public static final String OFFLINE_STAR_SEARCH = "starTitle"; + public static final String OFFLINE_STAR_SETTING = "starSetting"; + + public static final String CACHE_KEY_IGNORE = "ignoreArticles"; + public static final String CACHE_AUDIO_SESSION_ID = "audioSessionId"; + public static final String CACHE_BLOCK_TOKEN_USE = "blockTokenUse"; + + public static final String MAIN_BACK_STACK = "backStackIds"; + public static final String MAIN_BACK_STACK_SIZE = "backStackIdsSize"; + public static final String MAIN_NOW_PLAYING = "nowPlayingId"; + public static final String MAIN_NOW_PLAYING_SECONDARY = "nowPlayingSecondaryId"; + public static final String MAIN_SLIDE_PANEL_STATE = "slidePanelState"; + public static final String FRAGMENT_LIST = "fragmentList"; + public static final String FRAGMENT_LIST2 = "fragmentList2"; + public static final String FRAGMENT_EXTRA = "fragmentExtra"; + public static final String FRAGMENT_DOWNLOAD_FLIPPER = "fragmentDownloadFlipper"; + public static final String FRAGMENT_NAME = "fragmentName"; + public static final String FRAGMENT_POSITION = "fragmentPosition"; // Name of the preferences file. public static final String PREFERENCES_FILE_NAME = "net.nullsum.audinaut_preferences"; - public static final String OFFLINE_SYNC_NAME = "net.nullsum.audinaut.offline"; - public static final String OFFLINE_SYNC_DEFAULT = "syncDefaults"; + public static final String OFFLINE_SYNC_NAME = "net.nullsum.audinaut.offline"; + public static final String OFFLINE_SYNC_DEFAULT = "syncDefaults"; - // Account prefs - public static final String SYNC_ACCOUNT_NAME = "Subsonic Account"; - public static final String SYNC_ACCOUNT_TYPE = "Audinaut"; - public static final String SYNC_ACCOUNT_PLAYLIST_AUTHORITY = "net.nullsum.audinaut.playlists.provider"; - public static final String SYNC_ACCOUNT_MOST_RECENT_AUTHORITY = "net.nullsum.audinaut.mostrecent.provider"; + // Account prefs + public static final String SYNC_ACCOUNT_NAME = "Subsonic Account"; + public static final String SYNC_ACCOUNT_TYPE = "Audinaut"; + public static final String SYNC_ACCOUNT_PLAYLIST_AUTHORITY = "net.nullsum.audinaut.playlists.provider"; + public static final String SYNC_ACCOUNT_MOST_RECENT_AUTHORITY = "net.nullsum.audinaut.mostrecent.provider"; - public static final String TASKER_EXTRA_BUNDLE = "com.twofortyfouram.locale.intent.extra.BUNDLE"; + public static final String TASKER_EXTRA_BUNDLE = "com.twofortyfouram.locale.intent.extra.BUNDLE"; public static final String ALBUM_ART_FILE = "albumart.jpg"; diff --git a/app/src/main/java/net/nullsum/audinaut/util/DownloadFileItemHelperCallback.java b/app/src/main/java/net/nullsum/audinaut/util/DownloadFileItemHelperCallback.java index babc07c..8db0310 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/DownloadFileItemHelperCallback.java +++ b/app/src/main/java/net/nullsum/audinaut/util/DownloadFileItemHelperCallback.java @@ -15,100 +15,100 @@ import net.nullsum.audinaut.view.SongView; import net.nullsum.audinaut.view.UpdateView; public class DownloadFileItemHelperCallback extends ItemTouchHelper.SimpleCallback { - private static final String TAG = DownloadFileItemHelperCallback.class.getSimpleName(); + private static final String TAG = DownloadFileItemHelperCallback.class.getSimpleName(); - private SubsonicFragment fragment; - private boolean mainList; + private SubsonicFragment fragment; + private boolean mainList; - private BackgroundTask pendingTask = null; - private Deque pendingOperations = new ArrayDeque(); + private BackgroundTask pendingTask = null; + private Deque pendingOperations = new ArrayDeque(); - public DownloadFileItemHelperCallback(SubsonicFragment fragment, boolean mainList) { - super(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT); - this.fragment = fragment; - this.mainList = mainList; - } + public DownloadFileItemHelperCallback(SubsonicFragment fragment, boolean mainList) { + super(ItemTouchHelper.UP | ItemTouchHelper.DOWN, ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT); + this.fragment = fragment; + this.mainList = mainList; + } - @Override - public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder fromHolder, RecyclerView.ViewHolder toHolder) { - int from = fromHolder.getAdapterPosition(); - int to = toHolder.getAdapterPosition(); - getSectionAdapter().moveItem(from, to); + @Override + public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder fromHolder, RecyclerView.ViewHolder toHolder) { + int from = fromHolder.getAdapterPosition(); + int to = toHolder.getAdapterPosition(); + getSectionAdapter().moveItem(from, to); - synchronized (pendingOperations) { - pendingOperations.add(new Pair<>(from, to)); - updateDownloadService(); - } - return true; - } + synchronized (pendingOperations) { + pendingOperations.add(new Pair<>(from, to)); + updateDownloadService(); + } + return true; + } - @Override - public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { - SongView songView = (SongView) ((UpdateView.UpdateViewHolder) viewHolder).getUpdateView(); - DownloadFile downloadFile = songView.getDownloadFile(); + @Override + public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { + SongView songView = (SongView) ((UpdateView.UpdateViewHolder) viewHolder).getUpdateView(); + DownloadFile downloadFile = songView.getDownloadFile(); - getSectionAdapter().removeItem(downloadFile); - synchronized (pendingOperations) { - pendingOperations.add(downloadFile); - updateDownloadService(); - } - } + getSectionAdapter().removeItem(downloadFile); + synchronized (pendingOperations) { + pendingOperations.add(downloadFile); + updateDownloadService(); + } + } - public DownloadService getDownloadService() { - return fragment.getDownloadService(); - } - public SectionAdapter getSectionAdapter() { - return fragment.getCurrentAdapter(); - } + public DownloadService getDownloadService() { + return fragment.getDownloadService(); + } + public SectionAdapter getSectionAdapter() { + return fragment.getCurrentAdapter(); + } - private void updateDownloadService() { - if(pendingTask == null) { - final DownloadService downloadService = getDownloadService(); - if(downloadService == null) { - return; - } + private void updateDownloadService() { + if(pendingTask == null) { + final DownloadService downloadService = getDownloadService(); + if(downloadService == null) { + return; + } - pendingTask = new SilentBackgroundTask(downloadService) { - @Override - protected Void doInBackground() throws Throwable { - boolean running = true; - while(running) { - Object nextOperation = null; - synchronized (pendingOperations) { - if(!pendingOperations.isEmpty()) { - nextOperation = pendingOperations.remove(); - } - } + pendingTask = new SilentBackgroundTask(downloadService) { + @Override + protected Void doInBackground() throws Throwable { + boolean running = true; + while(running) { + Object nextOperation = null; + synchronized (pendingOperations) { + if(!pendingOperations.isEmpty()) { + nextOperation = pendingOperations.remove(); + } + } - if(nextOperation != null) { - if(nextOperation instanceof Pair) { - Pair swap = (Pair) nextOperation; - downloadService.swap(mainList, swap.getFirst(), swap.getSecond()); - } else if(nextOperation instanceof DownloadFile) { - DownloadFile downloadFile = (DownloadFile) nextOperation; - if(mainList) { - downloadService.remove(downloadFile); - } else { - downloadService.removeBackground(downloadFile); - } - } - } else { - running = false; - } - } + if(nextOperation != null) { + if(nextOperation instanceof Pair) { + Pair swap = (Pair) nextOperation; + downloadService.swap(mainList, swap.getFirst(), swap.getSecond()); + } else if(nextOperation instanceof DownloadFile) { + DownloadFile downloadFile = (DownloadFile) nextOperation; + if(mainList) { + downloadService.remove(downloadFile); + } else { + downloadService.removeBackground(downloadFile); + } + } + } else { + running = false; + } + } - synchronized (pendingOperations) { - pendingTask = null; + synchronized (pendingOperations) { + pendingTask = null; - // Start a task if this is non-empty. Means someone added while we were running operations - if(!pendingOperations.isEmpty()) { - updateDownloadService(); - } - } - return null; - } - }; - pendingTask.execute(); - } - } + // Start a task if this is non-empty. Means someone added while we were running operations + if(!pendingOperations.isEmpty()) { + updateDownloadService(); + } + } + return null; + } + }; + pendingTask.execute(); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/DrawableTint.java b/app/src/main/java/net/nullsum/audinaut/util/DrawableTint.java index f9f1800..76678ca 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/DrawableTint.java +++ b/app/src/main/java/net/nullsum/audinaut/util/DrawableTint.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.util; @@ -32,71 +32,71 @@ import java.util.WeakHashMap; import net.nullsum.audinaut.R; public class DrawableTint { - private static final Map attrMap = new HashMap<>(); - private static final WeakHashMap tintedDrawables = new WeakHashMap<>(); + private static final Map attrMap = new HashMap<>(); + private static final WeakHashMap tintedDrawables = new WeakHashMap<>(); - public static Drawable getTintedDrawable(Context context, @DrawableRes int drawableRes) { - return getTintedDrawable(context, drawableRes, R.attr.colorAccent); - } - public static Drawable getTintedDrawable(Context context, @DrawableRes int drawableRes, @AttrRes int colorAttr) { - if(tintedDrawables.containsKey(drawableRes)) { - return tintedDrawables.get(drawableRes); - } + public static Drawable getTintedDrawable(Context context, @DrawableRes int drawableRes) { + return getTintedDrawable(context, drawableRes, R.attr.colorAccent); + } + public static Drawable getTintedDrawable(Context context, @DrawableRes int drawableRes, @AttrRes int colorAttr) { + if(tintedDrawables.containsKey(drawableRes)) { + return tintedDrawables.get(drawableRes); + } - int color = getColorRes(context, colorAttr); - Drawable background = context.getResources().getDrawable(drawableRes); - background.setColorFilter(color, PorterDuff.Mode.SRC_IN); - tintedDrawables.put(drawableRes, background); - return background; - } - public static Drawable getTintedDrawableFromColor(Context context, @DrawableRes int drawableRes, @ColorRes int colorRes) { - if(tintedDrawables.containsKey(drawableRes)) { - return tintedDrawables.get(drawableRes); - } + int color = getColorRes(context, colorAttr); + Drawable background = context.getResources().getDrawable(drawableRes); + background.setColorFilter(color, PorterDuff.Mode.SRC_IN); + tintedDrawables.put(drawableRes, background); + return background; + } + public static Drawable getTintedDrawableFromColor(Context context, @DrawableRes int drawableRes, @ColorRes int colorRes) { + if(tintedDrawables.containsKey(drawableRes)) { + return tintedDrawables.get(drawableRes); + } - int color = context.getResources().getColor(colorRes); - Drawable background = context.getResources().getDrawable(drawableRes); - background.setColorFilter(color, PorterDuff.Mode.SRC_IN); - tintedDrawables.put(drawableRes, background); - return background; - } - public static int getColorRes(Context context, @AttrRes int colorAttr) { - int color; - if(attrMap.containsKey(colorAttr)) { - color = attrMap.get(colorAttr); - } else { - TypedValue typedValue = new TypedValue(); - Resources.Theme theme = context.getTheme(); - theme.resolveAttribute(colorAttr, typedValue, true); - color = typedValue.data; - attrMap.put(colorAttr, color); - } + int color = context.getResources().getColor(colorRes); + Drawable background = context.getResources().getDrawable(drawableRes); + background.setColorFilter(color, PorterDuff.Mode.SRC_IN); + tintedDrawables.put(drawableRes, background); + return background; + } + public static int getColorRes(Context context, @AttrRes int colorAttr) { + int color; + if(attrMap.containsKey(colorAttr)) { + color = attrMap.get(colorAttr); + } else { + TypedValue typedValue = new TypedValue(); + Resources.Theme theme = context.getTheme(); + theme.resolveAttribute(colorAttr, typedValue, true); + color = typedValue.data; + attrMap.put(colorAttr, color); + } - return color; - } - public static int getDrawableRes(Context context, @AttrRes int drawableAttr) { - if(attrMap.containsKey(drawableAttr)) { - return attrMap.get(drawableAttr); - } else { - int[] attrs = new int[]{drawableAttr}; - TypedArray typedArray = context.obtainStyledAttributes(attrs); - @DrawableRes int drawableRes = typedArray.getResourceId(0, 0); - typedArray.recycle(); - attrMap.put(drawableAttr, drawableRes); - return drawableRes; - } - } - public static Drawable getTintedAttrDrawable(Context context, @AttrRes int drawableAttr, @AttrRes int colorAttr) { - if(tintedDrawables.containsKey(drawableAttr)) { - return getTintedDrawable(context, attrMap.get(drawableAttr), colorAttr); - } + return color; + } + public static int getDrawableRes(Context context, @AttrRes int drawableAttr) { + if(attrMap.containsKey(drawableAttr)) { + return attrMap.get(drawableAttr); + } else { + int[] attrs = new int[]{drawableAttr}; + TypedArray typedArray = context.obtainStyledAttributes(attrs); + @DrawableRes int drawableRes = typedArray.getResourceId(0, 0); + typedArray.recycle(); + attrMap.put(drawableAttr, drawableRes); + return drawableRes; + } + } + public static Drawable getTintedAttrDrawable(Context context, @AttrRes int drawableAttr, @AttrRes int colorAttr) { + if(tintedDrawables.containsKey(drawableAttr)) { + return getTintedDrawable(context, attrMap.get(drawableAttr), colorAttr); + } - @DrawableRes int drawableRes = getDrawableRes(context, drawableAttr); - return getTintedDrawable(context, drawableRes, colorAttr); - } + @DrawableRes int drawableRes = getDrawableRes(context, drawableAttr); + return getTintedDrawable(context, drawableRes, colorAttr); + } - public static void wipeTintCache() { - attrMap.clear(); - tintedDrawables.clear(); - } + public static void wipeTintCache() { + attrMap.clear(); + tintedDrawables.clear(); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/EnvironmentVariables.java b/app/src/main/java/net/nullsum/audinaut/util/EnvironmentVariables.java index 9c82689..bbecfed 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/EnvironmentVariables.java +++ b/app/src/main/java/net/nullsum/audinaut/util/EnvironmentVariables.java @@ -1,20 +1,20 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2016 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2016 (C) Scott Jackson */ package net.nullsum.audinaut.util; public final class EnvironmentVariables { - public static final String PASTEBIN_DEV_KEY = ""; + public static final String PASTEBIN_DEV_KEY = ""; } diff --git a/app/src/main/java/net/nullsum/audinaut/util/FileProxy.java b/app/src/main/java/net/nullsum/audinaut/util/FileProxy.java index 388e488..1fb284d 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/FileProxy.java +++ b/app/src/main/java/net/nullsum/audinaut/util/FileProxy.java @@ -1,16 +1,16 @@ /* - This file is part of ServerProxy. - SocketProxy 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + This file is part of ServerProxy. + SocketProxy 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.util; @@ -29,191 +29,191 @@ import android.util.Log; import net.nullsum.audinaut.util.ServerProxy; public class FileProxy extends ServerProxy { - private static final String TAG = FileProxy.class.getSimpleName(); + private static final String TAG = FileProxy.class.getSimpleName(); - public FileProxy(Context context) { - super(context); - } + public FileProxy(Context context) { + super(context); + } - protected ProxyTask getTask(Socket client) { - return new StreamFileTask(client); - } + protected ProxyTask getTask(Socket client) { + return new StreamFileTask(client); + } - protected class StreamFileTask extends ProxyTask { - File file; + protected class StreamFileTask extends ProxyTask { + File file; - public StreamFileTask(Socket client) { - super(client); - } + public StreamFileTask(Socket client) { + super(client); + } - @Override - public boolean processRequest() { - if(!super.processRequest()) { - return false; - } + @Override + public boolean processRequest() { + if(!super.processRequest()) { + return false; + } - Log.i(TAG, "Processing request for file " + path); - file = getFile(path); - if (!file.exists()) { - Log.e(TAG, "File " + path + " does not exist"); - return false; - } + Log.i(TAG, "Processing request for file " + path); + file = getFile(path); + if (!file.exists()) { + Log.e(TAG, "File " + path + " does not exist"); + return false; + } - // Make sure to not try to read past where the file is downloaded - if(cbSkip != 0 && cbSkip >= file.length()) { - return false; - } + // Make sure to not try to read past where the file is downloaded + if(cbSkip != 0 && cbSkip >= file.length()) { + return false; + } - return true; - } + return true; + } - File getFile(String path) { - return new File(path); - } + File getFile(String path) { + return new File(path); + } - Long getContentLength() { - return file.length(); - } - long getFileSize() { - return file.length(); - } + Long getContentLength() { + return file.length(); + } + long getFileSize() { + return file.length(); + } - @Override - public void run() { - Long contentLength = getContentLength(); + @Override + public void run() { + Long contentLength = getContentLength(); - // Create HTTP header - String headers; - if(cbSkip == 0) { - headers = "HTTP/1.0 200 OK\r\n"; - } else { - headers = "HTTP/1.0 206 OK\r\n"; - headers += "Content-Range: bytes " + cbSkip + "-" + (file.length() - 1) + "/"; - if(contentLength == null) { - headers += "*"; - } else { - headers += contentLength; - } - headers += "\r\n"; + // Create HTTP header + String headers; + if(cbSkip == 0) { + headers = "HTTP/1.0 200 OK\r\n"; + } else { + headers = "HTTP/1.0 206 OK\r\n"; + headers += "Content-Range: bytes " + cbSkip + "-" + (file.length() - 1) + "/"; + if(contentLength == null) { + headers += "*"; + } else { + headers += contentLength; + } + headers += "\r\n"; - Log.i(TAG, "Streaming starts from: " + cbSkip); - } + Log.i(TAG, "Streaming starts from: " + cbSkip); + } - String name = file.getPath(); - int index = name.lastIndexOf('.'); - String ext = ""; - if(index != -1) { - ext = name.substring(index + 1).toLowerCase(); - } - if("mp3".equals(ext)) { - headers += "Content-Type: audio/mpeg\r\n"; - } else { - headers += "Content-Type: " + "application/octet-stream" + "\r\n"; - } + String name = file.getPath(); + int index = name.lastIndexOf('.'); + String ext = ""; + if(index != -1) { + ext = name.substring(index + 1).toLowerCase(); + } + if("mp3".equals(ext)) { + headers += "Content-Type: audio/mpeg\r\n"; + } else { + headers += "Content-Type: " + "application/octet-stream" + "\r\n"; + } - long fileSize; - if(contentLength == null) { - fileSize = getFileSize(); - } else { - fileSize = contentLength; - if(cbSkip > 0) { - headers += "Content-Length: " + (fileSize - cbSkip) + "\r\n"; - } else { - headers += "Content-Length: " + fileSize + "\r\n"; - } - headers += "Accept-Ranges: bytes \r\n"; - } - Log.i(TAG, "Streaming fileSize: " + fileSize); + long fileSize; + if(contentLength == null) { + fileSize = getFileSize(); + } else { + fileSize = contentLength; + if(cbSkip > 0) { + headers += "Content-Length: " + (fileSize - cbSkip) + "\r\n"; + } else { + headers += "Content-Length: " + fileSize + "\r\n"; + } + headers += "Accept-Ranges: bytes \r\n"; + } + Log.i(TAG, "Streaming fileSize: " + fileSize); - headers += "Connection: close\r\n"; - headers += "\r\n"; + headers += "Connection: close\r\n"; + headers += "\r\n"; - long cbToSend = fileSize - cbSkip; - OutputStream output = null; - byte[] buff = new byte[64 * 1024]; - try { - output = new BufferedOutputStream(client.getOutputStream(), 32*1024); - output.write(headers.getBytes()); + long cbToSend = fileSize - cbSkip; + OutputStream output = null; + byte[] buff = new byte[64 * 1024]; + try { + output = new BufferedOutputStream(client.getOutputStream(), 32*1024); + output.write(headers.getBytes()); - // Make sure to have file lock - onStart(); + // Make sure to have file lock + onStart(); - // Loop as long as there's stuff to send - while (isRunning && !client.isClosed()) { - onResume(); + // Loop as long as there's stuff to send + while (isRunning && !client.isClosed()) { + onResume(); - // See if there's more to send - int cbSentThisBatch = 0; - if (file.exists()) { - FileInputStream input = new FileInputStream(file); - input.skip(cbSkip); - int cbToSendThisBatch = input.available(); - while (cbToSendThisBatch > 0) { - int cbToRead = Math.min(cbToSendThisBatch, buff.length); - int cbRead = input.read(buff, 0, cbToRead); - if (cbRead == -1) { - break; - } - cbToSendThisBatch -= cbRead; - cbToSend -= cbRead; - output.write(buff, 0, cbRead); - output.flush(); - cbSkip += cbRead; - cbSentThisBatch += cbRead; - } - input.close(); - } + // See if there's more to send + int cbSentThisBatch = 0; + if (file.exists()) { + FileInputStream input = new FileInputStream(file); + input.skip(cbSkip); + int cbToSendThisBatch = input.available(); + while (cbToSendThisBatch > 0) { + int cbToRead = Math.min(cbToSendThisBatch, buff.length); + int cbRead = input.read(buff, 0, cbToRead); + if (cbRead == -1) { + break; + } + cbToSendThisBatch -= cbRead; + cbToSend -= cbRead; + output.write(buff, 0, cbRead); + output.flush(); + cbSkip += cbRead; + cbSentThisBatch += cbRead; + } + input.close(); + } - // Done regardless of whether or not it thinks it is - if(isWorkDone()) { - break; - } + // Done regardless of whether or not it thinks it is + if(isWorkDone()) { + break; + } - // If we did nothing this batch, block for a second - if (cbSentThisBatch == 0) { - Log.d(TAG, "Blocking until more data appears (" + cbToSend + ")"); - Thread.sleep(1000); - } - } + // If we did nothing this batch, block for a second + if (cbSentThisBatch == 0) { + Log.d(TAG, "Blocking until more data appears (" + cbToSend + ")"); + Thread.sleep(1000); + } + } - // Release file lock, use of stream proxy means nothing else is using it - onStop(); - } - catch (SocketException socketException) { - Log.e(TAG, "SocketException() thrown, proxy client has probably closed. This can exit harmlessly"); + // Release file lock, use of stream proxy means nothing else is using it + onStop(); + } + catch (SocketException socketException) { + Log.e(TAG, "SocketException() thrown, proxy client has probably closed. This can exit harmlessly"); - // Release file lock, use of stream proxy means nothing else is using it - onStop(); - } - catch (Exception e) { - Log.e(TAG, "Exception thrown from streaming task:"); - Log.e(TAG, e.getClass().getName() + " : " + e.getLocalizedMessage()); - } + // Release file lock, use of stream proxy means nothing else is using it + onStop(); + } + catch (Exception e) { + Log.e(TAG, "Exception thrown from streaming task:"); + Log.e(TAG, e.getClass().getName() + " : " + e.getLocalizedMessage()); + } - // Cleanup - try { - if (output != null) { - output.close(); - } - client.close(); - } - catch (IOException e) { - Log.e(TAG, "IOException while cleaning up streaming task:"); - Log.e(TAG, e.getClass().getName() + " : " + e.getLocalizedMessage()); - } - } + // Cleanup + try { + if (output != null) { + output.close(); + } + client.close(); + } + catch (IOException e) { + Log.e(TAG, "IOException while cleaning up streaming task:"); + Log.e(TAG, e.getClass().getName() + " : " + e.getLocalizedMessage()); + } + } - public void onStart() { + public void onStart() { - } - public void onStop() { + } + public void onStop() { - } - public void onResume() { + } + public void onResume() { - } - public boolean isWorkDone() { - return cbSkip >= file.length(); - } - } + } + public boolean isWorkDone() { + return cbSkip >= file.length(); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/FileUtil.java b/app/src/main/java/net/nullsum/audinaut/util/FileUtil.java index d9d2ede..c8cbd48 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/FileUtil.java +++ b/app/src/main/java/net/nullsum/audinaut/util/FileUtil.java @@ -65,47 +65,47 @@ public class FileUtil { private static final String[] FILE_SYSTEM_UNSAFE = {"/", "\\", "..", ":", "\"", "?", "*", "<", ">", "|"}; private static final String[] FILE_SYSTEM_UNSAFE_DIR = {"\\", "..", ":", "\"", "?", "*", "<", ">", "|"}; private static final List MUSIC_FILE_EXTENSIONS = Arrays.asList("mp3", "ogg", "aac", "flac", "m4a", "wav", "wma"); - private static final List PLAYLIST_FILE_EXTENSIONS = Arrays.asList("m3u"); - private static final int MAX_FILENAME_LENGTH = 254 - ".complete.mp3".length(); + private static final List PLAYLIST_FILE_EXTENSIONS = Arrays.asList("m3u"); + private static final int MAX_FILENAME_LENGTH = 254 - ".complete.mp3".length(); private static File DEFAULT_MUSIC_DIR; - private static final Kryo kryo = new Kryo(); - private static HashMap entryLookup; + private static final Kryo kryo = new Kryo(); + private static HashMap entryLookup; - static { - kryo.register(MusicDirectory.Entry.class); - kryo.register(Indexes.class); - kryo.register(Artist.class); - kryo.register(MusicFolder.class); - kryo.register(Playlist.class); - kryo.register(Genre.class); - } - - public static File getAnySong(Context context) { - File dir = getMusicDirectory(context); - return getAnySong(context, dir); - } - private static File getAnySong(Context context, File dir) { - for(File file: dir.listFiles()) { - if(file.isDirectory()) { - return getAnySong(context, file); - } - - String extension = getExtension(file.getName()); - if(MUSIC_FILE_EXTENSIONS.contains(extension)) { - return file; - } - } - - return null; - } - - public static File getEntryFile(Context context, MusicDirectory.Entry entry) { - if(entry.isDirectory()) { - return getAlbumDirectory(context, entry); - } else { - return getSongFile(context, entry); - } - } + static { + kryo.register(MusicDirectory.Entry.class); + kryo.register(Indexes.class); + kryo.register(Artist.class); + kryo.register(MusicFolder.class); + kryo.register(Playlist.class); + kryo.register(Genre.class); + } + + public static File getAnySong(Context context) { + File dir = getMusicDirectory(context); + return getAnySong(context, dir); + } + private static File getAnySong(Context context, File dir) { + for(File file: dir.listFiles()) { + if(file.isDirectory()) { + return getAnySong(context, file); + } + + String extension = getExtension(file.getName()); + if(MUSIC_FILE_EXTENSIONS.contains(extension)) { + return file; + } + } + + return null; + } + + public static File getEntryFile(Context context, MusicDirectory.Entry entry) { + if(entry.isDirectory()) { + return getAlbumDirectory(context, entry); + } else { + return getSongFile(context, entry); + } + } public static File getSongFile(Context context, MusicDirectory.Entry song) { File dir = getAlbumDirectory(context, song); @@ -120,230 +120,230 @@ public class FileUtil { } fileName.append(fileSystemSafe(song.getTitle())); - if(fileName.length() >= MAX_FILENAME_LENGTH) { - fileName.setLength(MAX_FILENAME_LENGTH); - } + if(fileName.length() >= MAX_FILENAME_LENGTH) { + fileName.setLength(MAX_FILENAME_LENGTH); + } - fileName.append("."); + fileName.append("."); if (song.getTranscodedSuffix() != null) { fileName.append(song.getTranscodedSuffix()); } else { fileName.append(song.getSuffix()); - } + } return new File(dir, fileName.toString()); } - public static File getPlaylistFile(Context context, String server, String name) { - File playlistDir = getPlaylistDirectory(context, server); - return new File(playlistDir, fileSystemSafe(name) + ".m3u"); - } - public static void writePlaylistFile(Context context, File file, MusicDirectory playlist) throws IOException { - FileWriter fw = new FileWriter(file); - BufferedWriter bw = new BufferedWriter(fw); - try { - fw.write("#EXTM3U\n"); - for (MusicDirectory.Entry e : playlist.getChildren()) { - String filePath = FileUtil.getSongFile(context, e).getAbsolutePath(); - if(! new File(filePath).exists()){ - String ext = FileUtil.getExtension(filePath); - String base = FileUtil.getBaseName(filePath); - filePath = base + ".complete." + ext; - } - fw.write(filePath + "\n"); - } - } catch(Exception e) { - Log.w(TAG, "Failed to save playlist: " + playlist.getName()); - } finally { - bw.close(); - fw.close(); - } - } - public static File getPlaylistDirectory(Context context) { - File playlistDir = new File(getSubsonicDirectory(context), "playlists"); - ensureDirectoryExistsAndIsReadWritable(playlistDir); - return playlistDir; - } - public static File getPlaylistDirectory(Context context, String server) { - File playlistDir = new File(getPlaylistDirectory(context), server); - ensureDirectoryExistsAndIsReadWritable(playlistDir); - return playlistDir; - } + public static File getPlaylistFile(Context context, String server, String name) { + File playlistDir = getPlaylistDirectory(context, server); + return new File(playlistDir, fileSystemSafe(name) + ".m3u"); + } + public static void writePlaylistFile(Context context, File file, MusicDirectory playlist) throws IOException { + FileWriter fw = new FileWriter(file); + BufferedWriter bw = new BufferedWriter(fw); + try { + fw.write("#EXTM3U\n"); + for (MusicDirectory.Entry e : playlist.getChildren()) { + String filePath = FileUtil.getSongFile(context, e).getAbsolutePath(); + if(! new File(filePath).exists()){ + String ext = FileUtil.getExtension(filePath); + String base = FileUtil.getBaseName(filePath); + filePath = base + ".complete." + ext; + } + fw.write(filePath + "\n"); + } + } catch(Exception e) { + Log.w(TAG, "Failed to save playlist: " + playlist.getName()); + } finally { + bw.close(); + fw.close(); + } + } + public static File getPlaylistDirectory(Context context) { + File playlistDir = new File(getSubsonicDirectory(context), "playlists"); + ensureDirectoryExistsAndIsReadWritable(playlistDir); + return playlistDir; + } + public static File getPlaylistDirectory(Context context, String server) { + File playlistDir = new File(getPlaylistDirectory(context), server); + ensureDirectoryExistsAndIsReadWritable(playlistDir); + return playlistDir; + } public static File getAlbumArtFile(Context context, MusicDirectory.Entry entry) { - if(entry.getId().indexOf(ImageLoader.PLAYLIST_PREFIX) != -1) { - File dir = getAlbumArtDirectory(context); - return new File(dir, Util.md5Hex(ImageLoader.PLAYLIST_PREFIX + entry.getTitle()) + ".jpeg"); - } else { - File albumDir = getAlbumDirectory(context, entry); - File artFile; - File albumFile = getAlbumArtFile(albumDir); - File hexFile = getHexAlbumArtFile(context, albumDir); - if (albumDir.exists()) { - if (hexFile.exists()) { - hexFile.renameTo(albumFile); - } - artFile = albumFile; - } else { - artFile = hexFile; - } - return artFile; - } + if(entry.getId().indexOf(ImageLoader.PLAYLIST_PREFIX) != -1) { + File dir = getAlbumArtDirectory(context); + return new File(dir, Util.md5Hex(ImageLoader.PLAYLIST_PREFIX + entry.getTitle()) + ".jpeg"); + } else { + File albumDir = getAlbumDirectory(context, entry); + File artFile; + File albumFile = getAlbumArtFile(albumDir); + File hexFile = getHexAlbumArtFile(context, albumDir); + if (albumDir.exists()) { + if (hexFile.exists()) { + hexFile.renameTo(albumFile); + } + artFile = albumFile; + } else { + artFile = hexFile; + } + return artFile; + } } public static File getAlbumArtFile(File albumDir) { return new File(albumDir, Constants.ALBUM_ART_FILE); } - public static File getHexAlbumArtFile(Context context, File albumDir) { - return new File(getAlbumArtDirectory(context), Util.md5Hex(albumDir.getPath()) + ".jpeg"); - } + public static File getHexAlbumArtFile(Context context, File albumDir) { + return new File(getAlbumArtDirectory(context), Util.md5Hex(albumDir.getPath()) + ".jpeg"); + } public static Bitmap getAlbumArtBitmap(Context context, MusicDirectory.Entry entry, int size) { File albumArtFile = getAlbumArtFile(context, entry); if (albumArtFile.exists()) { - final BitmapFactory.Options opt = new BitmapFactory.Options(); - opt.inJustDecodeBounds = true; - BitmapFactory.decodeFile(albumArtFile.getPath(), opt); - opt.inPurgeable = true; - opt.inSampleSize = Util.calculateInSampleSize(opt, size, Util.getScaledHeight(opt.outHeight, opt.outWidth, size)); - opt.inJustDecodeBounds = false; + final BitmapFactory.Options opt = new BitmapFactory.Options(); + opt.inJustDecodeBounds = true; + BitmapFactory.decodeFile(albumArtFile.getPath(), opt); + opt.inPurgeable = true; + opt.inSampleSize = Util.calculateInSampleSize(opt, size, Util.getScaledHeight(opt.outHeight, opt.outWidth, size)); + opt.inJustDecodeBounds = false; - Bitmap bitmap = BitmapFactory.decodeFile(albumArtFile.getPath(), opt); - return bitmap == null ? null : getScaledBitmap(bitmap, size); + Bitmap bitmap = BitmapFactory.decodeFile(albumArtFile.getPath(), opt); + return bitmap == null ? null : getScaledBitmap(bitmap, size); } return null; } - public static File getMiscDirectory(Context context) { - File dir = new File(getSubsonicDirectory(context), "misc"); - ensureDirectoryExistsAndIsReadWritable(dir); - ensureDirectoryExistsAndIsReadWritable(new File(dir, ".nomedia")); - return dir; - } + public static File getMiscDirectory(Context context) { + File dir = new File(getSubsonicDirectory(context), "misc"); + ensureDirectoryExistsAndIsReadWritable(dir); + ensureDirectoryExistsAndIsReadWritable(new File(dir, ".nomedia")); + return dir; + } - public static File getMiscFile(Context context, String url) { - return new File(getMiscDirectory(context), Util.md5Hex(url) + ".jpeg"); - } + public static File getMiscFile(Context context, String url) { + return new File(getMiscDirectory(context), Util.md5Hex(url) + ".jpeg"); + } - public static Bitmap getMiscBitmap(Context context, String url, int size) { - return null; - } + public static Bitmap getMiscBitmap(Context context, String url, int size) { + return null; + } - public static Bitmap getSampledBitmap(byte[] bytes, int size) { - return getSampledBitmap(bytes, size, true); - } - public static Bitmap getSampledBitmap(byte[] bytes, int size, boolean allowUnscaled) { - final BitmapFactory.Options opt = new BitmapFactory.Options(); - opt.inJustDecodeBounds = true; - BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt); - opt.inPurgeable = true; - opt.inSampleSize = Util.calculateInSampleSize(opt, size, Util.getScaledHeight(opt.outHeight, opt.outWidth, size)); - opt.inJustDecodeBounds = false; - Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt); - if(bitmap == null) { - return null; - } else { - return getScaledBitmap(bitmap, size, allowUnscaled); - } - } - public static Bitmap getScaledBitmap(Bitmap bitmap, int size) { - return getScaledBitmap(bitmap, size, true); - } - public static Bitmap getScaledBitmap(Bitmap bitmap, int size, boolean allowUnscaled) { - // Don't waste time scaling if the difference is minor - // Large album arts still need to be scaled since displayed as is on now playing! - if(allowUnscaled && size < 400 && bitmap.getWidth() < (size * 1.1)) { - return bitmap; - } else { - return Bitmap.createScaledBitmap(bitmap, size, Util.getScaledHeight(bitmap, size), true); - } - } + public static Bitmap getSampledBitmap(byte[] bytes, int size) { + return getSampledBitmap(bytes, size, true); + } + public static Bitmap getSampledBitmap(byte[] bytes, int size, boolean allowUnscaled) { + final BitmapFactory.Options opt = new BitmapFactory.Options(); + opt.inJustDecodeBounds = true; + BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt); + opt.inPurgeable = true; + opt.inSampleSize = Util.calculateInSampleSize(opt, size, Util.getScaledHeight(opt.outHeight, opt.outWidth, size)); + opt.inJustDecodeBounds = false; + Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opt); + if(bitmap == null) { + return null; + } else { + return getScaledBitmap(bitmap, size, allowUnscaled); + } + } + public static Bitmap getScaledBitmap(Bitmap bitmap, int size) { + return getScaledBitmap(bitmap, size, true); + } + public static Bitmap getScaledBitmap(Bitmap bitmap, int size, boolean allowUnscaled) { + // Don't waste time scaling if the difference is minor + // Large album arts still need to be scaled since displayed as is on now playing! + if(allowUnscaled && size < 400 && bitmap.getWidth() < (size * 1.1)) { + return bitmap; + } else { + return Bitmap.createScaledBitmap(bitmap, size, Util.getScaledHeight(bitmap, size), true); + } + } - public static File getAlbumArtDirectory(Context context) { - File albumArtDir = new File(getSubsonicDirectory(context), "artwork"); - ensureDirectoryExistsAndIsReadWritable(albumArtDir); - ensureDirectoryExistsAndIsReadWritable(new File(albumArtDir, ".nomedia")); - return albumArtDir; - } + public static File getAlbumArtDirectory(Context context) { + File albumArtDir = new File(getSubsonicDirectory(context), "artwork"); + ensureDirectoryExistsAndIsReadWritable(albumArtDir); + ensureDirectoryExistsAndIsReadWritable(new File(albumArtDir, ".nomedia")); + return albumArtDir; + } - public static File getArtistDirectory(Context context, Artist artist) { - File dir = new File(getMusicDirectory(context).getPath() + "/" + fileSystemSafe(artist.getName())); - return dir; - } - public static File getArtistDirectory(Context context, MusicDirectory.Entry artist) { - File dir = new File(getMusicDirectory(context).getPath() + "/" + fileSystemSafe(artist.getTitle())); - return dir; - } + public static File getArtistDirectory(Context context, Artist artist) { + File dir = new File(getMusicDirectory(context).getPath() + "/" + fileSystemSafe(artist.getName())); + return dir; + } + public static File getArtistDirectory(Context context, MusicDirectory.Entry artist) { + File dir = new File(getMusicDirectory(context).getPath() + "/" + fileSystemSafe(artist.getTitle())); + return dir; + } public static File getAlbumDirectory(Context context, MusicDirectory.Entry entry) { File dir = null; if (entry.getPath() != null) { File f = new File(fileSystemSafeDir(entry.getPath())); - String folder = getMusicDirectory(context).getPath(); - if(entry.isDirectory()) { - folder += "/" + f.getPath(); - } else if(f.getParent() != null) { - folder += "/" + f.getParent(); - } + String folder = getMusicDirectory(context).getPath(); + if(entry.isDirectory()) { + folder += "/" + f.getPath(); + } else if(f.getParent() != null) { + folder += "/" + f.getParent(); + } dir = new File(folder); } else { - MusicDirectory.Entry firstSong; - if(!Util.isOffline(context)) { - firstSong = lookupChild(context, entry, false); - if(firstSong != null) { - File songFile = FileUtil.getSongFile(context, firstSong); - dir = songFile.getParentFile(); - } - } + MusicDirectory.Entry firstSong; + if(!Util.isOffline(context)) { + firstSong = lookupChild(context, entry, false); + if(firstSong != null) { + File songFile = FileUtil.getSongFile(context, firstSong); + dir = songFile.getParentFile(); + } + } - if(dir == null) { - String artist = fileSystemSafe(entry.getArtist()); - String album = fileSystemSafe(entry.getAlbum()); - if("unnamed".equals(album)) { - album = fileSystemSafe(entry.getTitle()); - } - dir = new File(getMusicDirectory(context).getPath() + "/" + artist + "/" + album); - } + if(dir == null) { + String artist = fileSystemSafe(entry.getArtist()); + String album = fileSystemSafe(entry.getAlbum()); + if("unnamed".equals(album)) { + album = fileSystemSafe(entry.getTitle()); + } + dir = new File(getMusicDirectory(context).getPath() + "/" + artist + "/" + album); + } } return dir; } - public static MusicDirectory.Entry lookupChild(Context context, MusicDirectory.Entry entry, boolean allowDir) { - // Initialize lookupMap if first time called - String lookupName = Util.getCacheName(context, "entryLookup"); - if(entryLookup == null) { - entryLookup = deserialize(context, lookupName, HashMap.class); - - // Create it if - if(entryLookup == null) { - entryLookup = new HashMap(); - } - } - - // Check if this lookup has already been done before - MusicDirectory.Entry child = entryLookup.get(entry.getId()); - if(child != null) { - return child; - } - - // Do a special lookup since 4.7+ doesn't match artist/album to entry.getPath - String s = Util.getRestUrl(context, null, false) + entry.getId(); - String cacheName = (Util.isTagBrowsing(context) ? "album-" : "directory-") + s.hashCode() + ".ser"; - MusicDirectory entryDir = FileUtil.deserialize(context, cacheName, MusicDirectory.class); + public static MusicDirectory.Entry lookupChild(Context context, MusicDirectory.Entry entry, boolean allowDir) { + // Initialize lookupMap if first time called + String lookupName = Util.getCacheName(context, "entryLookup"); + if(entryLookup == null) { + entryLookup = deserialize(context, lookupName, HashMap.class); - if(entryDir != null) { - List songs = entryDir.getChildren(allowDir, true); - if(songs.size() > 0) { - child = songs.get(0); - entryLookup.put(entry.getId(), child); - serialize(context, entryLookup, lookupName); - return child; - } - } + // Create it if + if(entryLookup == null) { + entryLookup = new HashMap(); + } + } + + // Check if this lookup has already been done before + MusicDirectory.Entry child = entryLookup.get(entry.getId()); + if(child != null) { + return child; + } + + // Do a special lookup since 4.7+ doesn't match artist/album to entry.getPath + String s = Util.getRestUrl(context, null, false) + entry.getId(); + String cacheName = (Util.isTagBrowsing(context) ? "album-" : "directory-") + s.hashCode() + ".ser"; + MusicDirectory entryDir = FileUtil.deserialize(context, cacheName, MusicDirectory.class); + + if(entryDir != null) { + List songs = entryDir.getChildren(allowDir, true); + if(songs.size() > 0) { + child = songs.get(0); + entryLookup.put(entry.getId(), child); + serialize(context, entryLookup, lookupName); + return child; + } + } + + return null; + } - return null; - } - public static void createDirectoryForParent(File file) { File dir = file.getParentFile(); if (!dir.exists()) { @@ -366,149 +366,149 @@ public class FileUtil { } public static File getDefaultMusicDirectory(Context context) { - if(DEFAULT_MUSIC_DIR == null) { - File[] dirs; - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - dirs = context.getExternalMediaDirs(); - } else { - dirs = ContextCompat.getExternalFilesDirs(context, null); - } + if(DEFAULT_MUSIC_DIR == null) { + File[] dirs; + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + dirs = context.getExternalMediaDirs(); + } else { + dirs = ContextCompat.getExternalFilesDirs(context, null); + } - DEFAULT_MUSIC_DIR = new File(getBestDir(dirs), "music"); + DEFAULT_MUSIC_DIR = new File(getBestDir(dirs), "music"); - if (!DEFAULT_MUSIC_DIR.exists() && !DEFAULT_MUSIC_DIR.mkdirs()) { - Log.e(TAG, "Failed to create default dir " + DEFAULT_MUSIC_DIR); + if (!DEFAULT_MUSIC_DIR.exists() && !DEFAULT_MUSIC_DIR.mkdirs()) { + Log.e(TAG, "Failed to create default dir " + DEFAULT_MUSIC_DIR); - // Some devices seem to have screwed up the new media directory API. Go figure. Try again with standard locations - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - dirs = ContextCompat.getExternalFilesDirs(context, null); + // Some devices seem to have screwed up the new media directory API. Go figure. Try again with standard locations + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + dirs = ContextCompat.getExternalFilesDirs(context, null); - DEFAULT_MUSIC_DIR = new File(getBestDir(dirs), "music"); - if (!DEFAULT_MUSIC_DIR.exists() && !DEFAULT_MUSIC_DIR.mkdirs()) { - Log.e(TAG, "Failed to create default dir " + DEFAULT_MUSIC_DIR); - } else { - Log.w(TAG, "Stupid OEM's messed up media dir API added in 5.0"); - } - } - } - } + DEFAULT_MUSIC_DIR = new File(getBestDir(dirs), "music"); + if (!DEFAULT_MUSIC_DIR.exists() && !DEFAULT_MUSIC_DIR.mkdirs()) { + Log.e(TAG, "Failed to create default dir " + DEFAULT_MUSIC_DIR); + } else { + Log.w(TAG, "Stupid OEM's messed up media dir API added in 5.0"); + } + } + } + } return DEFAULT_MUSIC_DIR; } - private static File getBestDir(File[] dirs) { - // Past 5.0 we can query directly for SD Card - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - for(int i = 0; i < dirs.length; i++) { - try { - if (dirs[i] != null && Environment.isExternalStorageRemovable(dirs[i])) { - return dirs[i]; - } - } catch (Exception e) { - Log.e(TAG, "Failed to check if is external", e); - } - } - } + private static File getBestDir(File[] dirs) { + // Past 5.0 we can query directly for SD Card + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + for(int i = 0; i < dirs.length; i++) { + try { + if (dirs[i] != null && Environment.isExternalStorageRemovable(dirs[i])) { + return dirs[i]; + } + } catch (Exception e) { + Log.e(TAG, "Failed to check if is external", e); + } + } + } - // Before 5.0, we have to guess. Most of the time the SD card is last - for(int i = dirs.length - 1; i >= 0; i--) { - if(dirs[i] != null) { - return dirs[i]; - } - } + // Before 5.0, we have to guess. Most of the time the SD card is last + for(int i = dirs.length - 1; i >= 0; i--) { + if(dirs[i] != null) { + return dirs[i]; + } + } - // Should be impossible to be reached - return dirs[0]; - } + // Should be impossible to be reached + return dirs[0]; + } public static File getMusicDirectory(Context context) { String path = Util.getPreferences(context).getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, getDefaultMusicDirectory(context).getPath()); File dir = new File(path); return ensureDirectoryExistsAndIsReadWritable(dir) ? dir : getDefaultMusicDirectory(context); } - public static boolean deleteMusicDirectory(Context context) { - File musicDirectory = FileUtil.getMusicDirectory(context); - MediaStoreService mediaStore = new MediaStoreService(context); - return recursiveDelete(musicDirectory, mediaStore); - } - public static void deleteSerializedCache(Context context) { - for(File file: context.getCacheDir().listFiles()) { - if(file.getName().indexOf(".ser") != -1) { - file.delete(); - } - } - } - public static boolean deleteArtworkCache(Context context) { - File artDirectory = FileUtil.getAlbumArtDirectory(context); - return recursiveDelete(artDirectory); - } - public static boolean recursiveDelete(File dir) { - return recursiveDelete(dir, null); - } - public static boolean recursiveDelete(File dir, MediaStoreService mediaStore) { - if (dir != null && dir.exists()) { - File[] list = dir.listFiles(); - if(list != null) { - for(File file: list) { - if(file.isDirectory()) { - if(!recursiveDelete(file, mediaStore)) { - return false; - } - } else if(file.exists()) { - if(!file.delete()) { - return false; - } else if(mediaStore != null) { - mediaStore.deleteFromMediaStore(file); - } - } - } - } - return dir.delete(); - } - return false; - } + public static boolean deleteMusicDirectory(Context context) { + File musicDirectory = FileUtil.getMusicDirectory(context); + MediaStoreService mediaStore = new MediaStoreService(context); + return recursiveDelete(musicDirectory, mediaStore); + } + public static void deleteSerializedCache(Context context) { + for(File file: context.getCacheDir().listFiles()) { + if(file.getName().indexOf(".ser") != -1) { + file.delete(); + } + } + } + public static boolean deleteArtworkCache(Context context) { + File artDirectory = FileUtil.getAlbumArtDirectory(context); + return recursiveDelete(artDirectory); + } + public static boolean recursiveDelete(File dir) { + return recursiveDelete(dir, null); + } + public static boolean recursiveDelete(File dir, MediaStoreService mediaStore) { + if (dir != null && dir.exists()) { + File[] list = dir.listFiles(); + if(list != null) { + for(File file: list) { + if(file.isDirectory()) { + if(!recursiveDelete(file, mediaStore)) { + return false; + } + } else if(file.exists()) { + if(!file.delete()) { + return false; + } else if(mediaStore != null) { + mediaStore.deleteFromMediaStore(file); + } + } + } + } + return dir.delete(); + } + return false; + } - public static void deleteEmptyDir(File dir) { - try { - File[] children = dir.listFiles(); - if(children == null) { - return; - } + public static void deleteEmptyDir(File dir) { + try { + File[] children = dir.listFiles(); + if(children == null) { + return; + } - // No songs left in the folder - if (children.length == 1 && children[0].getPath().equals(FileUtil.getAlbumArtFile(dir).getPath())) { - Util.delete(children[0]); - children = dir.listFiles(); - } + // No songs left in the folder + if (children.length == 1 && children[0].getPath().equals(FileUtil.getAlbumArtFile(dir).getPath())) { + Util.delete(children[0]); + children = dir.listFiles(); + } - // Delete empty directory - if (children.length == 0) { - Util.delete(dir); - } - } catch(Exception e) { - Log.w(TAG, "Error while trying to delete empty dir", e); - } - } + // Delete empty directory + if (children.length == 0) { + Util.delete(dir); + } + } catch(Exception e) { + Log.w(TAG, "Error while trying to delete empty dir", e); + } + } - public static void unpinSong(Context context, File saveFile) { - // Don't try to unpin a song which isn't actually pinned - if(saveFile.getName().contains(".complete")) { - return; - } + public static void unpinSong(Context context, File saveFile) { + // Don't try to unpin a song which isn't actually pinned + if(saveFile.getName().contains(".complete")) { + return; + } - // Unpin file, rename to .complete - File completeFile = new File(saveFile.getParent(), FileUtil.getBaseName(saveFile.getName()) + - ".complete." + FileUtil.getExtension(saveFile.getName())); + // Unpin file, rename to .complete + File completeFile = new File(saveFile.getParent(), FileUtil.getBaseName(saveFile.getName()) + + ".complete." + FileUtil.getExtension(saveFile.getName())); - if(!saveFile.renameTo(completeFile)) { - Log.w(TAG, "Failed to upin " + saveFile + " to " + completeFile); - } else { - try { - new MediaStoreService(context).renameInMediaStore(completeFile, saveFile); - } catch(Exception e) { - Log.w(TAG, "Failed to write to media store"); - } - } - } + if(!saveFile.renameTo(completeFile)) { + Log.w(TAG, "Failed to upin " + saveFile + " to " + completeFile); + } else { + try { + new MediaStoreService(context).renameInMediaStore(completeFile, saveFile); + } catch(Exception e) { + Log.w(TAG, "Failed to write to media store"); + } + } + } public static boolean ensureDirectoryExistsAndIsReadWritable(File dir) { if (dir == null) { @@ -540,39 +540,39 @@ public class FileUtil { } return true; } - public static boolean verifyCanWrite(File dir) { - if(ensureDirectoryExistsAndIsReadWritable(dir)) { - try { - File tmp = new File(dir, "checkWrite"); - tmp.createNewFile(); - if(tmp.exists()) { - if(tmp.delete()) { - return true; - } else { - Log.w(TAG, "Failed to delete temp file, retrying"); - - // This should never be reached since this is a file Audinaut created! - Thread.sleep(100L); - tmp = new File(dir, "checkWrite"); - if(tmp.delete()) { - return true; - } else { - Log.w(TAG, "Failed retry to delete temp file"); - return false; - } - } - } else { - Log.w(TAG, "Temp file does not actually exist"); - return false; - } - } catch(Exception e) { - Log.w(TAG, "Failed to create tmp file", e); - return false; - } - } else { - return false; - } - } + public static boolean verifyCanWrite(File dir) { + if(ensureDirectoryExistsAndIsReadWritable(dir)) { + try { + File tmp = new File(dir, "checkWrite"); + tmp.createNewFile(); + if(tmp.exists()) { + if(tmp.delete()) { + return true; + } else { + Log.w(TAG, "Failed to delete temp file, retrying"); + + // This should never be reached since this is a file Audinaut created! + Thread.sleep(100L); + tmp = new File(dir, "checkWrite"); + if(tmp.delete()) { + return true; + } else { + Log.w(TAG, "Failed retry to delete temp file"); + return false; + } + } + } else { + Log.w(TAG, "Temp file does not actually exist"); + return false; + } + } catch(Exception e) { + Log.w(TAG, "Failed to create tmp file", e); + return false; + } + } else { + return false; + } + } /** * Makes a given filename safe by replacing special characters like slashes ("/" and "\") @@ -640,16 +640,16 @@ public class FileUtil { String extension = getExtension(file.getName()); return MUSIC_FILE_EXTENSIONS.contains(extension); } - - public static boolean isMusicFile(File file) { - String extension = getExtension(file.getName()); - return MUSIC_FILE_EXTENSIONS.contains(extension); - } - public static boolean isPlaylistFile(File file) { - String extension = getExtension(file.getName()); - return PLAYLIST_FILE_EXTENSIONS.contains(extension); - } + public static boolean isMusicFile(File file) { + String extension = getExtension(file.getName()); + return MUSIC_FILE_EXTENSIONS.contains(extension); + } + + public static boolean isPlaylistFile(File file) { + String extension = getExtension(file.getName()); + return PLAYLIST_FILE_EXTENSIONS.contains(extension); + } /** * Returns the extension (the substring after the last dot) of the given file. The dot @@ -674,125 +674,125 @@ public class FileUtil { int index = name.lastIndexOf('.'); return index == -1 ? name : name.substring(0, index); } - - public static Long[] getUsedSize(Context context, File file) { - long number = 0L; - long permanent = 0L; - long size = 0L; - - if(file.isFile()) { - if(isMediaFile(file)) { - if(file.getAbsolutePath().indexOf(".complete") == -1) { - permanent++; - } - return new Long[] {1L, permanent, file.length()}; - } else { - return new Long[] {0L, 0L, 0L}; - } - } else { - for (File child : FileUtil.listFiles(file)) { - Long[] pair = getUsedSize(context, child); - number += pair[0]; - permanent += pair[1]; - size += pair[2]; - } - return new Long[] {number, permanent, size}; - } - } + + public static Long[] getUsedSize(Context context, File file) { + long number = 0L; + long permanent = 0L; + long size = 0L; + + if(file.isFile()) { + if(isMediaFile(file)) { + if(file.getAbsolutePath().indexOf(".complete") == -1) { + permanent++; + } + return new Long[] {1L, permanent, file.length()}; + } else { + return new Long[] {0L, 0L, 0L}; + } + } else { + for (File child : FileUtil.listFiles(file)) { + Long[] pair = getUsedSize(context, child); + number += pair[0]; + permanent += pair[1]; + size += pair[2]; + } + return new Long[] {number, permanent, size}; + } + } public static boolean serialize(Context context, T obj, String fileName) { - Output out = null; - try { - RandomAccessFile file = new RandomAccessFile(context.getCacheDir() + "/" + fileName, "rw"); - out = new Output(new FileOutputStream(file.getFD())); - synchronized (kryo) { - kryo.writeObject(out, obj); - } - return true; - } catch (Throwable x) { - Log.w(TAG, "Failed to serialize object to " + fileName); - return false; - } finally { - Util.close(out); - } + Output out = null; + try { + RandomAccessFile file = new RandomAccessFile(context.getCacheDir() + "/" + fileName, "rw"); + out = new Output(new FileOutputStream(file.getFD())); + synchronized (kryo) { + kryo.writeObject(out, obj); + } + return true; + } catch (Throwable x) { + Log.w(TAG, "Failed to serialize object to " + fileName); + return false; + } finally { + Util.close(out); + } } - public static T deserialize(Context context, String fileName, Class tClass) { - return deserialize(context, fileName, tClass, 0); - } + public static T deserialize(Context context, String fileName, Class tClass) { + return deserialize(context, fileName, tClass, 0); + } public static T deserialize(Context context, String fileName, Class tClass, int hoursOld) { - Input in = null; - try { - File file = new File(context.getCacheDir(), fileName); - if(!file.exists()) { - return null; - } + Input in = null; + try { + File file = new File(context.getCacheDir(), fileName); + if(!file.exists()) { + return null; + } - if(hoursOld != 0) { - Date fileDate = new Date(file.lastModified()); - // Convert into hours - long age = (new Date().getTime() - fileDate.getTime()) / 1000 / 3600; - if(age > hoursOld) { - return null; - } - } + if(hoursOld != 0) { + Date fileDate = new Date(file.lastModified()); + // Convert into hours + long age = (new Date().getTime() - fileDate.getTime()) / 1000 / 3600; + if(age > hoursOld) { + return null; + } + } - RandomAccessFile randomFile = new RandomAccessFile(file, "r"); + RandomAccessFile randomFile = new RandomAccessFile(file, "r"); - in = new Input(new FileInputStream(randomFile.getFD())); - synchronized (kryo) { - T result = kryo.readObject(in, tClass); - return result; - } - } catch(FileNotFoundException e) { - // Different error message - Log.w(TAG, "No serialization for object from " + fileName); - return null; - } catch (Throwable x) { - Log.w(TAG, "Failed to deserialize object from " + fileName); - return null; - } finally { - Util.close(in); - } + in = new Input(new FileInputStream(randomFile.getFD())); + synchronized (kryo) { + T result = kryo.readObject(in, tClass); + return result; + } + } catch(FileNotFoundException e) { + // Different error message + Log.w(TAG, "No serialization for object from " + fileName); + return null; + } catch (Throwable x) { + Log.w(TAG, "Failed to deserialize object from " + fileName); + return null; + } finally { + Util.close(in); + } } - public static boolean serializeCompressed(Context context, T obj, String fileName) { - Output out = null; - try { - RandomAccessFile file = new RandomAccessFile(context.getCacheDir() + "/" + fileName, "rw"); - out = new Output(new DeflaterOutputStream(new FileOutputStream(file.getFD()))); - synchronized (kryo) { - kryo.writeObject(out, obj); - } - return true; - } catch (Throwable x) { - Log.w(TAG, "Failed to serialize compressed object to " + fileName); - return false; - } finally { - Util.close(out); - } - } + public static boolean serializeCompressed(Context context, T obj, String fileName) { + Output out = null; + try { + RandomAccessFile file = new RandomAccessFile(context.getCacheDir() + "/" + fileName, "rw"); + out = new Output(new DeflaterOutputStream(new FileOutputStream(file.getFD()))); + synchronized (kryo) { + kryo.writeObject(out, obj); + } + return true; + } catch (Throwable x) { + Log.w(TAG, "Failed to serialize compressed object to " + fileName); + return false; + } finally { + Util.close(out); + } + } - public static T deserializeCompressed(Context context, String fileName, Class tClass) { - Input in = null; - try { - RandomAccessFile file = new RandomAccessFile(context.getCacheDir() + "/" + fileName, "r"); + public static T deserializeCompressed(Context context, String fileName, Class tClass) { + Input in = null; + try { + RandomAccessFile file = new RandomAccessFile(context.getCacheDir() + "/" + fileName, "r"); - in = new Input(new InflaterInputStream(new FileInputStream(file.getFD()))); - synchronized (kryo) { - T result = kryo.readObject(in, tClass); - return result; - } - } catch(FileNotFoundException e) { - // Different error message - Log.w(TAG, "No serialization compressed for object from " + fileName); - return null; - } catch (Throwable x) { - Log.w(TAG, "Failed to deserialize compressed object from " + fileName); - return null; - } finally { - Util.close(in); - } - } + in = new Input(new InflaterInputStream(new FileInputStream(file.getFD()))); + synchronized (kryo) { + T result = kryo.readObject(in, tClass); + return result; + } + } catch(FileNotFoundException e) { + // Different error message + Log.w(TAG, "No serialization compressed for object from " + fileName); + return null; + } catch (Throwable x) { + Log.w(TAG, "Failed to deserialize compressed object from " + fileName); + return null; + } finally { + Util.close(in); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/ImageLoader.java b/app/src/main/java/net/nullsum/audinaut/util/ImageLoader.java index 1c6a91d..35dae3c 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/ImageLoader.java +++ b/app/src/main/java/net/nullsum/audinaut/util/ImageLoader.java @@ -54,386 +54,386 @@ import net.nullsum.audinaut.service.MusicServiceFactory; * @author Sindre Mehus */ public class ImageLoader { - private static final String TAG = ImageLoader.class.getSimpleName(); - public static final String PLAYLIST_PREFIX = "pl-"; + private static final String TAG = ImageLoader.class.getSimpleName(); + public static final String PLAYLIST_PREFIX = "pl-"; - private Context context; - private LruCache cache; - private Handler handler; - private Bitmap nowPlaying; - private Bitmap nowPlayingSmall; - private final int imageSizeDefault; - private final int imageSizeLarge; - private boolean clearingCache = false; - private final int cacheSize; + private Context context; + private LruCache cache; + private Handler handler; + private Bitmap nowPlaying; + private Bitmap nowPlayingSmall; + private final int imageSizeDefault; + private final int imageSizeLarge; + private boolean clearingCache = false; + private final int cacheSize; - private final static int[] COLORS = {0xFF33B5E5, 0xFFAA66CC, 0xFF99CC00, 0xFFFFBB33, 0xFFFF4444}; + private final static int[] COLORS = {0xFF33B5E5, 0xFFAA66CC, 0xFF99CC00, 0xFFFFBB33, 0xFFFF4444}; - public ImageLoader(Context context) { - this.context = context; - handler = new Handler(Looper.getMainLooper()); - final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); - cacheSize = maxMemory / 4; + public ImageLoader(Context context) { + this.context = context; + handler = new Handler(Looper.getMainLooper()); + final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); + cacheSize = maxMemory / 4; - // Determine the density-dependent image sizes. - imageSizeDefault = context.getResources().getDrawable(R.drawable.unknown_album).getIntrinsicHeight(); - DisplayMetrics metrics = context.getResources().getDisplayMetrics(); - imageSizeLarge = Math.round(Math.min(metrics.widthPixels, metrics.heightPixels)); + // Determine the density-dependent image sizes. + imageSizeDefault = context.getResources().getDrawable(R.drawable.unknown_album).getIntrinsicHeight(); + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + imageSizeLarge = Math.round(Math.min(metrics.widthPixels, metrics.heightPixels)); - cache = new LruCache(cacheSize) { - @Override - protected int sizeOf(String key, Bitmap bitmap) { - return bitmap.getRowBytes() * bitmap.getHeight() / 1024; - } + cache = new LruCache(cacheSize) { + @Override + protected int sizeOf(String key, Bitmap bitmap) { + return bitmap.getRowBytes() * bitmap.getHeight() / 1024; + } - @Override - protected void entryRemoved(boolean evicted, String key, Bitmap oldBitmap, Bitmap newBitmap) { - if(evicted) { - if((oldBitmap != nowPlaying && oldBitmap != nowPlayingSmall) || clearingCache) { - oldBitmap.recycle(); - } else if(oldBitmap != newBitmap) { - cache.put(key, oldBitmap); - } - } - } - }; - } + @Override + protected void entryRemoved(boolean evicted, String key, Bitmap oldBitmap, Bitmap newBitmap) { + if(evicted) { + if((oldBitmap != nowPlaying && oldBitmap != nowPlayingSmall) || clearingCache) { + oldBitmap.recycle(); + } else if(oldBitmap != newBitmap) { + cache.put(key, oldBitmap); + } + } + } + }; + } - public void clearCache() { - nowPlaying = null; - nowPlayingSmall = null; - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - clearingCache = true; - cache.evictAll(); - clearingCache = false; - return null; - } - }.execute(); - } - public void onLowMemory(float percent) { - Log.i(TAG, "Cache size: " + cache.size() + " => " + Math.round(cacheSize * (1 - percent)) + " out of " + cache.maxSize()); - cache.resize(Math.round(cacheSize * (1 - percent))); - } - public void onUIVisible() { - if(cache.maxSize() != cacheSize) { - Log.i(TAG, "Returned to full cache size"); - cache.resize(cacheSize); - } - } + public void clearCache() { + nowPlaying = null; + nowPlayingSmall = null; + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + clearingCache = true; + cache.evictAll(); + clearingCache = false; + return null; + } + }.execute(); + } + public void onLowMemory(float percent) { + Log.i(TAG, "Cache size: " + cache.size() + " => " + Math.round(cacheSize * (1 - percent)) + " out of " + cache.maxSize()); + cache.resize(Math.round(cacheSize * (1 - percent))); + } + public void onUIVisible() { + if(cache.maxSize() != cacheSize) { + Log.i(TAG, "Returned to full cache size"); + cache.resize(cacheSize); + } + } - public void setNowPlayingSmall(Bitmap bitmap) { - nowPlayingSmall = bitmap; - } + public void setNowPlayingSmall(Bitmap bitmap) { + nowPlayingSmall = bitmap; + } - private Bitmap getUnknownImage(MusicDirectory.Entry entry, int size) { - String key; - int color; - if(entry == null) { - key = getKey("unknown", size); - color = COLORS[0]; + private Bitmap getUnknownImage(MusicDirectory.Entry entry, int size) { + String key; + int color; + if(entry == null) { + key = getKey("unknown", size); + color = COLORS[0]; - return getUnknownImage(key, size, color, null, null); - } else { - key = getKey(entry.getId() + "unknown", size); - String hash; - if(entry.getAlbum() != null) { - hash = entry.getAlbum(); - } else if(entry.getArtist() != null) { - hash = entry.getArtist(); - } else { - hash = entry.getId(); - } - color = COLORS[Math.abs(hash.hashCode()) % COLORS.length]; + return getUnknownImage(key, size, color, null, null); + } else { + key = getKey(entry.getId() + "unknown", size); + String hash; + if(entry.getAlbum() != null) { + hash = entry.getAlbum(); + } else if(entry.getArtist() != null) { + hash = entry.getArtist(); + } else { + hash = entry.getId(); + } + color = COLORS[Math.abs(hash.hashCode()) % COLORS.length]; - return getUnknownImage(key, size, color, entry.getAlbum(), entry.getArtist()); - } - } - private Bitmap getUnknownImage(String key, int size, int color, String topText, String bottomText) { - Bitmap bitmap = cache.get(key); - if(bitmap == null) { - bitmap = createUnknownImage(size, color, topText, bottomText); - cache.put(key, bitmap); - } + return getUnknownImage(key, size, color, entry.getAlbum(), entry.getArtist()); + } + } + private Bitmap getUnknownImage(String key, int size, int color, String topText, String bottomText) { + Bitmap bitmap = cache.get(key); + if(bitmap == null) { + bitmap = createUnknownImage(size, color, topText, bottomText); + cache.put(key, bitmap); + } - return bitmap; - } - private Bitmap createUnknownImage(int size, int primaryColor, String topText, String bottomText) { - Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); + return bitmap; + } + private Bitmap createUnknownImage(int size, int primaryColor, String topText, String bottomText) { + Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); - Paint color = new Paint(); - color.setColor(primaryColor); - canvas.drawRect(0, 0, size, size * 2.0f / 3.0f, color); + Paint color = new Paint(); + color.setColor(primaryColor); + canvas.drawRect(0, 0, size, size * 2.0f / 3.0f, color); - color.setShader(new LinearGradient(0, 0, 0, size / 3.0f, Color.rgb(82, 82, 82), Color.BLACK, Shader.TileMode.MIRROR)); - canvas.drawRect(0, size * 2.0f / 3.0f, size, size, color); + color.setShader(new LinearGradient(0, 0, 0, size / 3.0f, Color.rgb(82, 82, 82), Color.BLACK, Shader.TileMode.MIRROR)); + canvas.drawRect(0, size * 2.0f / 3.0f, size, size, color); - if(topText != null || bottomText != null) { - Paint font = new Paint(); - font.setFlags(Paint.ANTI_ALIAS_FLAG); - font.setColor(Color.WHITE); - font.setTextSize(3.0f + size * 0.07f); + if(topText != null || bottomText != null) { + Paint font = new Paint(); + font.setFlags(Paint.ANTI_ALIAS_FLAG); + font.setColor(Color.WHITE); + font.setTextSize(3.0f + size * 0.07f); - if(topText != null) { - canvas.drawText(topText, size * 0.05f, size * 0.6f, font); - } + if(topText != null) { + canvas.drawText(topText, size * 0.05f, size * 0.6f, font); + } - if(bottomText != null) { - canvas.drawText(bottomText, size * 0.05f, size * 0.8f, font); - } - } + if(bottomText != null) { + canvas.drawText(bottomText, size * 0.05f, size * 0.8f, font); + } + } - return bitmap; - } + return bitmap; + } - public Bitmap getCachedImage(Context context, MusicDirectory.Entry entry, boolean large) { - int size = large ? imageSizeLarge : imageSizeDefault; - if(entry == null || entry.getCoverArt() == null) { - return getUnknownImage(entry, size); - } + public Bitmap getCachedImage(Context context, MusicDirectory.Entry entry, boolean large) { + int size = large ? imageSizeLarge : imageSizeDefault; + if(entry == null || entry.getCoverArt() == null) { + return getUnknownImage(entry, size); + } - Bitmap bitmap = cache.get(getKey(entry.getCoverArt(), size)); - if(bitmap == null || bitmap.isRecycled()) { - bitmap = FileUtil.getAlbumArtBitmap(context, entry, size); - String key = getKey(entry.getCoverArt(), size); - cache.put(key, bitmap); - cache.get(key); - } + Bitmap bitmap = cache.get(getKey(entry.getCoverArt(), size)); + if(bitmap == null || bitmap.isRecycled()) { + bitmap = FileUtil.getAlbumArtBitmap(context, entry, size); + String key = getKey(entry.getCoverArt(), size); + cache.put(key, bitmap); + cache.get(key); + } - if(bitmap != null && bitmap.isRecycled()) { - bitmap = null; - } - return bitmap; - } + if(bitmap != null && bitmap.isRecycled()) { + bitmap = null; + } + return bitmap; + } - public SilentBackgroundTask loadImage(View view, MusicDirectory.Entry entry, boolean large, boolean crossfade) { - int size = large ? imageSizeLarge : imageSizeDefault; - return loadImage(view, entry, large, size, crossfade); - } - public SilentBackgroundTask loadImage(View view, MusicDirectory.Entry entry, boolean large, int size, boolean crossfade) { - // If we know this a artist, try to load artist info instead - if(entry != null && !entry.isAlbum() && !Util.isOffline(context)) { - SilentBackgroundTask task = new ArtistImageTask(view.getContext(), entry, size, imageSizeLarge, large, view, crossfade); - task.execute(); - return task; - } else if(entry != null && entry.getCoverArt() == null && entry.isDirectory() && !Util.isOffline(context)) { - // Try to lookup child cover art - MusicDirectory.Entry firstChild = FileUtil.lookupChild(context, entry, true); - if(firstChild != null) { - entry.setCoverArt(firstChild.getCoverArt()); - } - } + public SilentBackgroundTask loadImage(View view, MusicDirectory.Entry entry, boolean large, boolean crossfade) { + int size = large ? imageSizeLarge : imageSizeDefault; + return loadImage(view, entry, large, size, crossfade); + } + public SilentBackgroundTask loadImage(View view, MusicDirectory.Entry entry, boolean large, int size, boolean crossfade) { + // If we know this a artist, try to load artist info instead + if(entry != null && !entry.isAlbum() && !Util.isOffline(context)) { + SilentBackgroundTask task = new ArtistImageTask(view.getContext(), entry, size, imageSizeLarge, large, view, crossfade); + task.execute(); + return task; + } else if(entry != null && entry.getCoverArt() == null && entry.isDirectory() && !Util.isOffline(context)) { + // Try to lookup child cover art + MusicDirectory.Entry firstChild = FileUtil.lookupChild(context, entry, true); + if(firstChild != null) { + entry.setCoverArt(firstChild.getCoverArt()); + } + } - Bitmap bitmap; - if (entry == null || entry.getCoverArt() == null) { - bitmap = getUnknownImage(entry, size); - setImage(view, Util.createDrawableFromBitmap(context, bitmap), crossfade); - return null; - } + Bitmap bitmap; + if (entry == null || entry.getCoverArt() == null) { + bitmap = getUnknownImage(entry, size); + setImage(view, Util.createDrawableFromBitmap(context, bitmap), crossfade); + return null; + } - bitmap = cache.get(getKey(entry.getCoverArt(), size)); - if (bitmap != null && !bitmap.isRecycled()) { - final Drawable drawable = Util.createDrawableFromBitmap(this.context, bitmap); - setImage(view, drawable, crossfade); - if(large) { - nowPlaying = bitmap; - } - return null; - } + bitmap = cache.get(getKey(entry.getCoverArt(), size)); + if (bitmap != null && !bitmap.isRecycled()) { + final Drawable drawable = Util.createDrawableFromBitmap(this.context, bitmap); + setImage(view, drawable, crossfade); + if(large) { + nowPlaying = bitmap; + } + return null; + } - if (!large) { - setImage(view, null, false); - } - ImageTask task = new ViewImageTask(view.getContext(), entry, size, imageSizeLarge, large, view, crossfade); - task.execute(); - return task; - } + if (!large) { + setImage(view, null, false); + } + ImageTask task = new ViewImageTask(view.getContext(), entry, size, imageSizeLarge, large, view, crossfade); + task.execute(); + return task; + } - public SilentBackgroundTask loadImage(View view, String url, boolean large) { - Bitmap bitmap; - int size = large ? imageSizeLarge : imageSizeDefault; - if (url == null) { - String key = getKey(url + "unknown", size); - int color = COLORS[Math.abs(key.hashCode()) % COLORS.length]; - bitmap = getUnknownImage(key, size, color, null, null); - setImage(view, Util.createDrawableFromBitmap(context, bitmap), true); - return null; - } + public SilentBackgroundTask loadImage(View view, String url, boolean large) { + Bitmap bitmap; + int size = large ? imageSizeLarge : imageSizeDefault; + if (url == null) { + String key = getKey(url + "unknown", size); + int color = COLORS[Math.abs(key.hashCode()) % COLORS.length]; + bitmap = getUnknownImage(key, size, color, null, null); + setImage(view, Util.createDrawableFromBitmap(context, bitmap), true); + return null; + } - bitmap = cache.get(getKey(url, size)); - if (bitmap != null && !bitmap.isRecycled()) { - final Drawable drawable = Util.createDrawableFromBitmap(this.context, bitmap); - setImage(view, drawable, true); - return null; - } - setImage(view, null, false); + bitmap = cache.get(getKey(url, size)); + if (bitmap != null && !bitmap.isRecycled()) { + final Drawable drawable = Util.createDrawableFromBitmap(this.context, bitmap); + setImage(view, drawable, true); + return null; + } + setImage(view, null, false); - SilentBackgroundTask task = new ViewUrlTask(view.getContext(), view, url, size); - task.execute(); - return task; - } + SilentBackgroundTask task = new ViewUrlTask(view.getContext(), view, url, size); + task.execute(); + return task; + } - public SilentBackgroundTask loadImage(View view, Playlist playlist, boolean large, boolean crossfade) { - MusicDirectory.Entry entry = new MusicDirectory.Entry(); - String id; - if(Util.isOffline(context)) { - id = PLAYLIST_PREFIX + playlist.getName(); - entry.setTitle(playlist.getComment()); - } else { - id = PLAYLIST_PREFIX + playlist.getId(); - entry.setTitle(playlist.getName()); - } - entry.setId(id); - entry.setCoverArt(id); - // So this isn't treated as a artist - entry.setParent(""); + public SilentBackgroundTask loadImage(View view, Playlist playlist, boolean large, boolean crossfade) { + MusicDirectory.Entry entry = new MusicDirectory.Entry(); + String id; + if(Util.isOffline(context)) { + id = PLAYLIST_PREFIX + playlist.getName(); + entry.setTitle(playlist.getComment()); + } else { + id = PLAYLIST_PREFIX + playlist.getId(); + entry.setTitle(playlist.getName()); + } + entry.setId(id); + entry.setCoverArt(id); + // So this isn't treated as a artist + entry.setParent(""); - return loadImage(view, entry, large, crossfade); - } + return loadImage(view, entry, large, crossfade); + } - private String getKey(String coverArtId, int size) { - return coverArtId + size; - } + private String getKey(String coverArtId, int size) { + return coverArtId + size; + } - private void setImage(View view, final Drawable drawable, boolean crossfade) { - if (view instanceof TextView) { - // Cross-fading is not implemented for TextView since it's not in use. It would be easy to add it, though. - TextView textView = (TextView) view; - textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null); - } else if (view instanceof ImageView) { - final ImageView imageView = (ImageView) view; - if (crossfade && drawable != null) { - Drawable existingDrawable = imageView.getDrawable(); - if (existingDrawable == null) { - Bitmap emptyImage; - if(drawable.getIntrinsicWidth() > 0 && drawable.getIntrinsicHeight() > 0) { - emptyImage = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); - } else { - emptyImage = Bitmap.createBitmap(imageSizeDefault, imageSizeDefault, Bitmap.Config.ARGB_8888); - } - existingDrawable = new BitmapDrawable(context.getResources(), emptyImage); - } else if(existingDrawable instanceof TransitionDrawable) { - // This should only ever be used if user is skipping through many songs quickly - TransitionDrawable tmp = (TransitionDrawable) existingDrawable; - existingDrawable = tmp.getDrawable(tmp.getNumberOfLayers() - 1); - } - if(existingDrawable != null && drawable != null) { - Drawable[] layers = new Drawable[]{existingDrawable, drawable}; - final TransitionDrawable transitionDrawable = new TransitionDrawable(layers); - imageView.setImageDrawable(transitionDrawable); - transitionDrawable.startTransition(250); + private void setImage(View view, final Drawable drawable, boolean crossfade) { + if (view instanceof TextView) { + // Cross-fading is not implemented for TextView since it's not in use. It would be easy to add it, though. + TextView textView = (TextView) view; + textView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null); + } else if (view instanceof ImageView) { + final ImageView imageView = (ImageView) view; + if (crossfade && drawable != null) { + Drawable existingDrawable = imageView.getDrawable(); + if (existingDrawable == null) { + Bitmap emptyImage; + if(drawable.getIntrinsicWidth() > 0 && drawable.getIntrinsicHeight() > 0) { + emptyImage = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); + } else { + emptyImage = Bitmap.createBitmap(imageSizeDefault, imageSizeDefault, Bitmap.Config.ARGB_8888); + } + existingDrawable = new BitmapDrawable(context.getResources(), emptyImage); + } else if(existingDrawable instanceof TransitionDrawable) { + // This should only ever be used if user is skipping through many songs quickly + TransitionDrawable tmp = (TransitionDrawable) existingDrawable; + existingDrawable = tmp.getDrawable(tmp.getNumberOfLayers() - 1); + } + if(existingDrawable != null && drawable != null) { + Drawable[] layers = new Drawable[]{existingDrawable, drawable}; + final TransitionDrawable transitionDrawable = new TransitionDrawable(layers); + imageView.setImageDrawable(transitionDrawable); + transitionDrawable.startTransition(250); - // Get rid of transition drawable after transition occurs - handler.postDelayed(new Runnable() { - @Override - public void run() { - // Only execute if still on same transition drawable - if (imageView.getDrawable() == transitionDrawable) { - imageView.setImageDrawable(drawable); - } - } - }, 500L); - } else { - imageView.setImageDrawable(drawable); - } - } else { - imageView.setImageDrawable(drawable); - } - } - } + // Get rid of transition drawable after transition occurs + handler.postDelayed(new Runnable() { + @Override + public void run() { + // Only execute if still on same transition drawable + if (imageView.getDrawable() == transitionDrawable) { + imageView.setImageDrawable(drawable); + } + } + }, 500L); + } else { + imageView.setImageDrawable(drawable); + } + } else { + imageView.setImageDrawable(drawable); + } + } + } - public abstract class ImageTask extends SilentBackgroundTask { - private final Context mContext; - protected final MusicDirectory.Entry mEntry; - private final int mSize; - private final int mSaveSize; - private final boolean mIsNowPlaying; - protected Drawable mDrawable; + public abstract class ImageTask extends SilentBackgroundTask { + private final Context mContext; + protected final MusicDirectory.Entry mEntry; + private final int mSize; + private final int mSaveSize; + private final boolean mIsNowPlaying; + protected Drawable mDrawable; - public ImageTask(Context context, MusicDirectory.Entry entry, int size, int saveSize, boolean isNowPlaying) { - super(context); - mContext = context; - mEntry = entry; - mSize = size; - mSaveSize = saveSize; - mIsNowPlaying = isNowPlaying; - } + public ImageTask(Context context, MusicDirectory.Entry entry, int size, int saveSize, boolean isNowPlaying) { + super(context); + mContext = context; + mEntry = entry; + mSize = size; + mSaveSize = saveSize; + mIsNowPlaying = isNowPlaying; + } - @Override - protected Void doInBackground() throws Throwable { - try { - MusicService musicService = MusicServiceFactory.getMusicService(mContext); - Bitmap bitmap = musicService.getCoverArt(mContext, mEntry, mSize, null, this); - if(bitmap != null) { - String key = getKey(mEntry.getCoverArt(), mSize); - cache.put(key, bitmap); - // Make sure key is the most recently "used" - cache.get(key); - if (mIsNowPlaying) { - nowPlaying = bitmap; - } - } else { - bitmap = getUnknownImage(mEntry, mSize); - } + @Override + protected Void doInBackground() throws Throwable { + try { + MusicService musicService = MusicServiceFactory.getMusicService(mContext); + Bitmap bitmap = musicService.getCoverArt(mContext, mEntry, mSize, null, this); + if(bitmap != null) { + String key = getKey(mEntry.getCoverArt(), mSize); + cache.put(key, bitmap); + // Make sure key is the most recently "used" + cache.get(key); + if (mIsNowPlaying) { + nowPlaying = bitmap; + } + } else { + bitmap = getUnknownImage(mEntry, mSize); + } - mDrawable = Util.createDrawableFromBitmap(mContext, bitmap); - } catch (Throwable x) { - Log.e(TAG, "Failed to download album art.", x); - cancelled.set(true); - } + mDrawable = Util.createDrawableFromBitmap(mContext, bitmap); + } catch (Throwable x) { + Log.e(TAG, "Failed to download album art.", x); + cancelled.set(true); + } - return null; - } - } + return null; + } + } - private class ViewImageTask extends ImageTask { - protected boolean mCrossfade; - private View mView; + private class ViewImageTask extends ImageTask { + protected boolean mCrossfade; + private View mView; - public ViewImageTask(Context context, MusicDirectory.Entry entry, int size, int saveSize, boolean isNowPlaying, View view, boolean crossfade) { - super(context, entry, size, saveSize, isNowPlaying); + public ViewImageTask(Context context, MusicDirectory.Entry entry, int size, int saveSize, boolean isNowPlaying, View view, boolean crossfade) { + super(context, entry, size, saveSize, isNowPlaying); - mView = view; - mCrossfade = crossfade; - } + mView = view; + mCrossfade = crossfade; + } - @Override - protected void done(Void result) { - setImage(mView, mDrawable, mCrossfade); - } - } + @Override + protected void done(Void result) { + setImage(mView, mDrawable, mCrossfade); + } + } - private class ArtistImageTask extends SilentBackgroundTask { - private final Context mContext; - private final MusicDirectory.Entry mEntry; - private final int mSize; - private final int mSaveSize; - private final boolean mIsNowPlaying; - private Drawable mDrawable; - private boolean mCrossfade; - private View mView; + private class ArtistImageTask extends SilentBackgroundTask { + private final Context mContext; + private final MusicDirectory.Entry mEntry; + private final int mSize; + private final int mSaveSize; + private final boolean mIsNowPlaying; + private Drawable mDrawable; + private boolean mCrossfade; + private View mView; - private SilentBackgroundTask subTask; + private SilentBackgroundTask subTask; - public ArtistImageTask(Context context, MusicDirectory.Entry entry, int size, int saveSize, boolean isNowPlaying, View view, boolean crossfade) { - super(context); - mContext = context; - mEntry = entry; - mSize = size; - mSaveSize = saveSize; - mIsNowPlaying = isNowPlaying; - mView = view; - mCrossfade = crossfade; - } + public ArtistImageTask(Context context, MusicDirectory.Entry entry, int size, int saveSize, boolean isNowPlaying, View view, boolean crossfade) { + super(context); + mContext = context; + mEntry = entry; + mSize = size; + mSaveSize = saveSize; + mIsNowPlaying = isNowPlaying; + mView = view; + mCrossfade = crossfade; + } - @Override - protected Void doInBackground() throws Throwable { - try { - MusicService musicService = MusicServiceFactory.getMusicService(mContext); + @Override + protected Void doInBackground() throws Throwable { + try { + MusicService musicService = MusicServiceFactory.getMusicService(mContext); - // Figure out whether we are going to get a artist image or the standard image + // Figure out whether we are going to get a artist image or the standard image if (mEntry != null && mEntry.getCoverArt() == null && mEntry.isDirectory() && !Util.isOffline(context)) { // Try to lookup child cover art MusicDirectory.Entry firstChild = FileUtil.lookupChild(context, mEntry, true); @@ -451,72 +451,72 @@ public class ImageLoader { return null; } - // Execute whichever way we decided to go - subTask.doInBackground(); - } catch (Throwable x) { - Log.e(TAG, "Failed to get artist info", x); - cancelled.set(true); - } - return null; - } + // Execute whichever way we decided to go + subTask.doInBackground(); + } catch (Throwable x) { + Log.e(TAG, "Failed to get artist info", x); + cancelled.set(true); + } + return null; + } - @Override - public void done(Void result) { - if(subTask != null) { - subTask.done(result); - } else if(mDrawable != null) { - setImage(mView, mDrawable, mCrossfade); - } - } - } + @Override + public void done(Void result) { + if(subTask != null) { + subTask.done(result); + } else if(mDrawable != null) { + setImage(mView, mDrawable, mCrossfade); + } + } + } - private class ViewUrlTask extends SilentBackgroundTask { - private final Context mContext; - private final String mUrl; - private final ImageView mView; - private Drawable mDrawable; - private int mSize; + private class ViewUrlTask extends SilentBackgroundTask { + private final Context mContext; + private final String mUrl; + private final ImageView mView; + private Drawable mDrawable; + private int mSize; - public ViewUrlTask(Context context, View view, String url, int size) { - super(context); - mContext = context; - mView = (ImageView) view; - mUrl = url; - mSize = size; - } + public ViewUrlTask(Context context, View view, String url, int size) { + super(context); + mContext = context; + mView = (ImageView) view; + mUrl = url; + mSize = size; + } - @Override - protected Void doInBackground() throws Throwable { - try { - MusicService musicService = MusicServiceFactory.getMusicService(mContext); - Bitmap bitmap = musicService.getBitmap(mUrl, mSize, mContext, null, this); - if(bitmap != null) { - String key = getKey(mUrl, mSize); - cache.put(key, bitmap); - // Make sure key is the most recently "used" - cache.get(key); + @Override + protected Void doInBackground() throws Throwable { + try { + MusicService musicService = MusicServiceFactory.getMusicService(mContext); + Bitmap bitmap = musicService.getBitmap(mUrl, mSize, mContext, null, this); + if(bitmap != null) { + String key = getKey(mUrl, mSize); + cache.put(key, bitmap); + // Make sure key is the most recently "used" + cache.get(key); - mDrawable = Util.createDrawableFromBitmap(mContext, bitmap); - } - } catch (Throwable x) { - Log.e(TAG, "Failed to download from url " + mUrl, x); - cancelled.set(true); - } + mDrawable = Util.createDrawableFromBitmap(mContext, bitmap); + } + } catch (Throwable x) { + Log.e(TAG, "Failed to download from url " + mUrl, x); + cancelled.set(true); + } - return null; - } + return null; + } - @Override - protected void done(Void result) { - if(mDrawable != null) { - mView.setImageDrawable(mDrawable); - } else { - failedToDownload(); - } - } + @Override + protected void done(Void result) { + if(mDrawable != null) { + mView.setImageDrawable(mDrawable); + } else { + failedToDownload(); + } + } - protected void failedToDownload() { + protected void failedToDownload() { - } - } + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/LoadingTask.java b/app/src/main/java/net/nullsum/audinaut/util/LoadingTask.java index a0d607d..5d34a62 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/LoadingTask.java +++ b/app/src/main/java/net/nullsum/audinaut/util/LoadingTask.java @@ -13,61 +13,61 @@ import net.nullsum.audinaut.activity.SubsonicActivity; public abstract class LoadingTask extends BackgroundTask { private final Activity tabActivity; - private ProgressDialog loading; - private final boolean cancellable; + private ProgressDialog loading; + private final boolean cancellable; - public LoadingTask(Activity activity) { - super(activity); - tabActivity = activity; - this.cancellable = true; - } + public LoadingTask(Activity activity) { + super(activity); + tabActivity = activity; + this.cancellable = true; + } public LoadingTask(Activity activity, final boolean cancellable) { super(activity); tabActivity = activity; - this.cancellable = cancellable; + this.cancellable = cancellable; } @Override public void execute() { loading = ProgressDialog.show(tabActivity, "", "Loading. Please Wait...", true, cancellable, new DialogInterface.OnCancelListener() { - public void onCancel(DialogInterface dialog) { - cancel(); - } - }); + public void onCancel(DialogInterface dialog) { + cancel(); + } + }); - queue.offer(task = new Task() { - @Override - public void onDone(T result) { - if(loading.isShowing()) { - loading.dismiss(); - } - done(result); - } + queue.offer(task = new Task() { + @Override + public void onDone(T result) { + if(loading.isShowing()) { + loading.dismiss(); + } + done(result); + } - @Override - public void onError(Throwable t) { - if(loading.isShowing()) { - loading.dismiss(); - } - error(t); - } - }); + @Override + public void onError(Throwable t) { + if(loading.isShowing()) { + loading.dismiss(); + } + error(t); + } + }); } - @Override + @Override public boolean isCancelled() { return (tabActivity instanceof SubsonicActivity && ((SubsonicActivity) tabActivity).isDestroyedCompat()) || cancelled.get(); } - - @Override + + @Override public void updateProgress(final String message) { - if(!cancelled.get()) { - getHandler().post(new Runnable() { - @Override - public void run() { - loading.setMessage(message); - } - }); - } + if(!cancelled.get()) { + getHandler().post(new Runnable() { + @Override + public void run() { + loading.setMessage(message); + } + }); + } } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/MenuUtil.java b/app/src/main/java/net/nullsum/audinaut/util/MenuUtil.java index 84e41a2..2566e23 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/MenuUtil.java +++ b/app/src/main/java/net/nullsum/audinaut/util/MenuUtil.java @@ -1,16 +1,16 @@ /* - This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + This file is part of Subsonic. + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.util; @@ -31,53 +31,53 @@ import net.nullsum.audinaut.view.SongView; import net.nullsum.audinaut.view.UpdateView; public final class MenuUtil { - private final static String TAG = MenuUtil.class.getSimpleName(); + private final static String TAG = MenuUtil.class.getSimpleName(); - public static void hideMenuItems(Context context, Menu menu, UpdateView updateView) { - if(!Util.isOffline(context)) { - // If we are looking at a standard song view, get downloadFile to cache what options to show - if(updateView instanceof SongView) { - SongView songView = (SongView) updateView; - DownloadFile downloadFile = songView.getDownloadFile(); + public static void hideMenuItems(Context context, Menu menu, UpdateView updateView) { + if(!Util.isOffline(context)) { + // If we are looking at a standard song view, get downloadFile to cache what options to show + if(updateView instanceof SongView) { + SongView songView = (SongView) updateView; + DownloadFile downloadFile = songView.getDownloadFile(); - try { - if(downloadFile != null) { - if(downloadFile.isWorkDone()) { - // Remove permanent cache menu if already perma cached - if(downloadFile.isSaved()) { - menu.setGroupVisible(R.id.hide_pin, false); - } + try { + if(downloadFile != null) { + if(downloadFile.isWorkDone()) { + // Remove permanent cache menu if already perma cached + if(downloadFile.isSaved()) { + menu.setGroupVisible(R.id.hide_pin, false); + } - // Remove cache option no matter what if already downloaded - menu.setGroupVisible(R.id.hide_download, false); - } else { - // Remove delete option if nothing to delete - menu.setGroupVisible(R.id.hide_delete, false); - } - } - } catch(Exception e) { - Log.w(TAG, "Failed to lookup downloadFile info", e); - } - } - // Apply similar logic to album views - else if(updateView instanceof AlbumView || updateView instanceof ArtistView || updateView instanceof ArtistEntryView) { - File folder = null; - if(updateView instanceof AlbumView) { - folder = ((AlbumView) updateView).getFile(); - } else if(updateView instanceof ArtistView) { - folder = ((ArtistView) updateView).getFile(); - } else if(updateView instanceof ArtistEntryView) { - folder = ((ArtistEntryView) updateView).getFile(); - } + // Remove cache option no matter what if already downloaded + menu.setGroupVisible(R.id.hide_download, false); + } else { + // Remove delete option if nothing to delete + menu.setGroupVisible(R.id.hide_delete, false); + } + } + } catch(Exception e) { + Log.w(TAG, "Failed to lookup downloadFile info", e); + } + } + // Apply similar logic to album views + else if(updateView instanceof AlbumView || updateView instanceof ArtistView || updateView instanceof ArtistEntryView) { + File folder = null; + if(updateView instanceof AlbumView) { + folder = ((AlbumView) updateView).getFile(); + } else if(updateView instanceof ArtistView) { + folder = ((ArtistView) updateView).getFile(); + } else if(updateView instanceof ArtistEntryView) { + folder = ((ArtistEntryView) updateView).getFile(); + } - try { - if(folder != null && !folder.exists()) { - menu.setGroupVisible(R.id.hide_delete, false); - } - } catch(Exception e) { - Log.w(TAG, "Failed to lookup album directory info", e); - } - } - } - } + try { + if(folder != null && !folder.exists()) { + menu.setGroupVisible(R.id.hide_delete, false); + } + } catch(Exception e) { + Log.w(TAG, "Failed to lookup album directory info", e); + } + } + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/ProgressListener.java b/app/src/main/java/net/nullsum/audinaut/util/ProgressListener.java index 933ac8e..9f9dedd 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/ProgressListener.java +++ b/app/src/main/java/net/nullsum/audinaut/util/ProgressListener.java @@ -24,5 +24,5 @@ package net.nullsum.audinaut.util; public interface ProgressListener { void updateProgress(String message); void updateProgress(int messageId); - void updateCache(int changeCode); + void updateCache(int changeCode); } diff --git a/app/src/main/java/net/nullsum/audinaut/util/ServerProxy.java b/app/src/main/java/net/nullsum/audinaut/util/ServerProxy.java index 3cb0ccc..04bf12f 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/ServerProxy.java +++ b/app/src/main/java/net/nullsum/audinaut/util/ServerProxy.java @@ -1,16 +1,16 @@ /* - This file is part of ServerProxy. - SocketProxy 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + This file is part of ServerProxy. + SocketProxy 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.util; @@ -40,192 +40,192 @@ import android.net.wifi.WifiManager; import android.util.Log; public abstract class ServerProxy implements Runnable { - private static final String TAG = ServerProxy.class.getSimpleName(); + private static final String TAG = ServerProxy.class.getSimpleName(); - private Thread thread; - protected boolean isRunning; - private ServerSocket socket; - private int port; - private Context context; + private Thread thread; + protected boolean isRunning; + private ServerSocket socket; + private int port; + private Context context; - public ServerProxy(Context context) { - // Create listening socket - try { - socket = new ServerSocket(0); - socket.setSoTimeout(5000); - port = socket.getLocalPort(); - this.context = context; - } catch (UnknownHostException e) { // impossible - } catch (IOException e) { - Log.e(TAG, "IOException initializing server", e); - } - } + public ServerProxy(Context context) { + // Create listening socket + try { + socket = new ServerSocket(0); + socket.setSoTimeout(5000); + port = socket.getLocalPort(); + this.context = context; + } catch (UnknownHostException e) { // impossible + } catch (IOException e) { + Log.e(TAG, "IOException initializing server", e); + } + } - public void start() { - if(socket.isBound()) { - thread = new Thread(this, "Socket Proxy"); - thread.start(); - } else { - Log.e(TAG, "Attempting to start a non-initialized proxy"); - } - } + public void start() { + if(socket.isBound()) { + thread = new Thread(this, "Socket Proxy"); + thread.start(); + } else { + Log.e(TAG, "Attempting to start a non-initialized proxy"); + } + } - public void stop() { - isRunning = false; - if(thread != null) { - thread.interrupt(); - } - } + public void stop() { + isRunning = false; + if(thread != null) { + thread.interrupt(); + } + } - public String getPrivateAddress(String request) { - return getAddress("127.0.0.1", request); - } - public String getPublicAddress(String request) { - WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); - int ipAddress = wifiManager.getConnectionInfo().getIpAddress(); + public String getPrivateAddress(String request) { + return getAddress("127.0.0.1", request); + } + public String getPublicAddress(String request) { + WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); + int ipAddress = wifiManager.getConnectionInfo().getIpAddress(); - if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) { - ipAddress = Integer.reverseBytes(ipAddress); - } + if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) { + ipAddress = Integer.reverseBytes(ipAddress); + } - byte[] ipByteArray = BigInteger.valueOf(ipAddress).toByteArray(); - String ipAddressString = null; - try { - ipAddressString = InetAddress.getByAddress(ipByteArray).getHostAddress(); - } catch(UnknownHostException ex) { - Log.e(TAG, "Unable to get host address."); - } + byte[] ipByteArray = BigInteger.valueOf(ipAddress).toByteArray(); + String ipAddressString = null; + try { + ipAddressString = InetAddress.getByAddress(ipByteArray).getHostAddress(); + } catch(UnknownHostException ex) { + Log.e(TAG, "Unable to get host address."); + } - return getAddress(ipAddressString, request); - } - private String getAddress(String host, String request) { - try { - return String.format("http://%s:%d/%s", host, port, URLEncoder.encode(request, "UTF-8")); - } catch (UnsupportedEncodingException e) { - return null; - } - } + return getAddress(ipAddressString, request); + } + private String getAddress(String host, String request) { + try { + return String.format("http://%s:%d/%s", host, port, URLEncoder.encode(request, "UTF-8")); + } catch (UnsupportedEncodingException e) { + return null; + } + } - @Override - public void run() { - isRunning = true; - while (isRunning) { - try { - Socket client = socket.accept(); - if (client == null) { - continue; - } - Log.i(TAG, "client connected"); + @Override + public void run() { + isRunning = true; + while (isRunning) { + try { + Socket client = socket.accept(); + if (client == null) { + continue; + } + Log.i(TAG, "client connected"); - ProxyTask task = getTask(client); - if (task.processRequest()) { - new Thread(task, "ProxyTask").start(); - } + ProxyTask task = getTask(client); + if (task.processRequest()) { + new Thread(task, "ProxyTask").start(); + } - } catch (SocketTimeoutException e) { - // Do nothing - } catch (IOException e) { - Log.e(TAG, "Error connecting to client", e); - } - } - Log.i(TAG, "Proxy interrupted. Shutting down."); - } + } catch (SocketTimeoutException e) { + // Do nothing + } catch (IOException e) { + Log.e(TAG, "Error connecting to client", e); + } + } + Log.i(TAG, "Proxy interrupted. Shutting down."); + } - abstract ProxyTask getTask(Socket client); + abstract ProxyTask getTask(Socket client); - protected abstract class ProxyTask implements Runnable { - protected Socket client; - protected String path; - protected int cbSkip = 0; - protected Map requestHeaders = new HashMap<>(); + protected abstract class ProxyTask implements Runnable { + protected Socket client; + protected String path; + protected int cbSkip = 0; + protected Map requestHeaders = new HashMap<>(); - public ProxyTask(Socket client) { - this.client = client; - } + public ProxyTask(Socket client) { + this.client = client; + } - protected boolean readRequest() { - InputStream is; - String firstLine; - BufferedReader reader; - try { - is = client.getInputStream(); - reader = new BufferedReader(new InputStreamReader(is), 8192); - firstLine = reader.readLine(); - } catch (IOException e) { - Log.e(TAG, "Error parsing request", e); - return false; - } + protected boolean readRequest() { + InputStream is; + String firstLine; + BufferedReader reader; + try { + is = client.getInputStream(); + reader = new BufferedReader(new InputStreamReader(is), 8192); + firstLine = reader.readLine(); + } catch (IOException e) { + Log.e(TAG, "Error parsing request", e); + return false; + } - if (firstLine == null) { - Log.i(TAG, "Proxy client closed connection without a request."); - return false; - } + if (firstLine == null) { + Log.i(TAG, "Proxy client closed connection without a request."); + return false; + } - StringTokenizer st = new StringTokenizer(firstLine); - if(!st.hasMoreTokens()) { - Log.w(TAG, "Unknown request with no tokens"); - return false; - } else if(st.countTokens() < 2) { - Log.w(TAG, "Unknown request with no uri: \"" + firstLine + '"'); - return false; - } - String method = st.nextToken(); - String uri = st.nextToken(); - String realUri = uri.substring(1); + StringTokenizer st = new StringTokenizer(firstLine); + if(!st.hasMoreTokens()) { + Log.w(TAG, "Unknown request with no tokens"); + return false; + } else if(st.countTokens() < 2) { + Log.w(TAG, "Unknown request with no uri: \"" + firstLine + '"'); + return false; + } + String method = st.nextToken(); + String uri = st.nextToken(); + String realUri = uri.substring(1); - // Process path - try { - path = URLDecoder.decode(realUri, "UTF-8"); - } catch (UnsupportedEncodingException e) { - Log.e(TAG, "Unsupported encoding", e); - return false; - } + // Process path + try { + path = URLDecoder.decode(realUri, "UTF-8"); + } catch (UnsupportedEncodingException e) { + Log.e(TAG, "Unsupported encoding", e); + return false; + } - // Get all of the headers - try { - String line; - while((line = reader.readLine()) != null && !"".equals(line)) { - int index = line.indexOf(':'); - // Ignore headers without ':' or where ':' is the last thing in the string - if(index != -1 && (index + 2) < line.length()) { - String headerName = line.substring(0, index); - String headerValue = line.substring(index + 2); + // Get all of the headers + try { + String line; + while((line = reader.readLine()) != null && !"".equals(line)) { + int index = line.indexOf(':'); + // Ignore headers without ':' or where ':' is the last thing in the string + if(index != -1 && (index + 2) < line.length()) { + String headerName = line.substring(0, index); + String headerValue = line.substring(index + 2); - requestHeaders.put(headerName, headerValue); - } - } - } catch(IOException e) { - // Don't really care once past first line - } catch(Exception e) { - Log.w(TAG, "Exception reading request", e); - } + requestHeaders.put(headerName, headerValue); + } + } + } catch(IOException e) { + // Don't really care once past first line + } catch(Exception e) { + Log.w(TAG, "Exception reading request", e); + } - return true; - } + return true; + } - public boolean processRequest() { - if (!readRequest()) { - return false; - } - Log.i(TAG, "Processing request for " + path); + public boolean processRequest() { + if (!readRequest()) { + return false; + } + Log.i(TAG, "Processing request for " + path); - // Try to get range requested - String range = requestHeaders.get("Range"); - if(range != null) { - int index = range.indexOf("="); - if(index >= 0) { - range = range.substring(index + 1); + // Try to get range requested + String range = requestHeaders.get("Range"); + if(range != null) { + int index = range.indexOf("="); + if(index >= 0) { + range = range.substring(index + 1); - index = range.indexOf("-"); - if(index > 0) { - range = range.substring(0, index); - } + index = range.indexOf("-"); + if(index > 0) { + range = range.substring(0, index); + } - cbSkip = Integer.parseInt(range); - } - } + cbSkip = Integer.parseInt(range); + } + } - return true; - } - } + return true; + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/SettingsBackupAgent.java b/app/src/main/java/net/nullsum/audinaut/util/SettingsBackupAgent.java index b3e81fd..dd63fc9 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/SettingsBackupAgent.java +++ b/app/src/main/java/net/nullsum/audinaut/util/SettingsBackupAgent.java @@ -1,20 +1,20 @@ /* - This file is part of Subsonic. - - Subsonic 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. - - Subsonic 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 Subsonic. If not, see . - - Copyright 2009 (C) Sindre Mehus + This file is part of Subsonic. + + Subsonic 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. + + Subsonic 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 Subsonic. If not, see . + + Copyright 2009 (C) Sindre Mehus */ package net.nullsum.audinaut.util; @@ -29,16 +29,16 @@ import java.io.IOException; import net.nullsum.audinaut.util.Constants; public class SettingsBackupAgent extends BackupAgentHelper { - @Override - public void onCreate() { - super.onCreate(); - SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, Constants.PREFERENCES_FILE_NAME); - addHelper("mypreferences", helper); - } + @Override + public void onCreate() { + super.onCreate(); + SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, Constants.PREFERENCES_FILE_NAME); + addHelper("mypreferences", helper); + } - @Override - public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException{ - super.onRestore(data, appVersionCode, newState); - Util.getPreferences(this).edit().remove(Constants.PREFERENCES_KEY_CACHE_LOCATION).apply(); - } + @Override + public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException{ + super.onRestore(data, appVersionCode, newState); + Util.getPreferences(this).edit().remove(Constants.PREFERENCES_KEY_CACHE_LOCATION).apply(); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/ShufflePlayBuffer.java b/app/src/main/java/net/nullsum/audinaut/util/ShufflePlayBuffer.java index 3491e53..67b6a98 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/ShufflePlayBuffer.java +++ b/app/src/main/java/net/nullsum/audinaut/util/ShufflePlayBuffer.java @@ -40,173 +40,173 @@ import net.nullsum.audinaut.util.FileUtil; */ public class ShufflePlayBuffer { - private static final String TAG = ShufflePlayBuffer.class.getSimpleName(); - private static final String CACHE_FILENAME = "shuffleBuffer.ser"; + private static final String TAG = ShufflePlayBuffer.class.getSimpleName(); + private static final String CACHE_FILENAME = "shuffleBuffer.ser"; - private ScheduledExecutorService executorService; - private Runnable runnable; - private boolean firstRun = true; - private final ArrayList buffer = new ArrayList(); - private int lastCount = -1; - private DownloadService context; - private boolean awaitingResults = false; - private int capacity; - private int refillThreshold; + private ScheduledExecutorService executorService; + private Runnable runnable; + private boolean firstRun = true; + private final ArrayList buffer = new ArrayList(); + private int lastCount = -1; + private DownloadService context; + private boolean awaitingResults = false; + private int capacity; + private int refillThreshold; - private SharedPreferences.OnSharedPreferenceChangeListener listener; - private int currentServer; - private String currentFolder = ""; - private String genre = ""; - private String startYear = ""; - private String endYear = ""; + private SharedPreferences.OnSharedPreferenceChangeListener listener; + private int currentServer; + private String currentFolder = ""; + private String genre = ""; + private String startYear = ""; + private String endYear = ""; - public ShufflePlayBuffer(DownloadService context) { - this.context = context; + public ShufflePlayBuffer(DownloadService context) { + this.context = context; - executorService = Executors.newSingleThreadScheduledExecutor(); - runnable = new Runnable() { - @Override - public void run() { - refill(); - } - }; - executorService.scheduleWithFixedDelay(runnable, 1, 10, TimeUnit.SECONDS); - - // Calculate out the capacity and refill threshold based on the user's random size preference - int shuffleListSize = Math.max(1, Integer.parseInt(Util.getPreferences(context).getString(Constants.PREFERENCES_KEY_RANDOM_SIZE, "20"))); - // ex: default 20 -> 50 - capacity = shuffleListSize * 5 / 2; - capacity = Math.min(500, capacity); - - // ex: default 20 -> 40 - refillThreshold = capacity * 4 / 5; - } + executorService = Executors.newSingleThreadScheduledExecutor(); + runnable = new Runnable() { + @Override + public void run() { + refill(); + } + }; + executorService.scheduleWithFixedDelay(runnable, 1, 10, TimeUnit.SECONDS); - public List get(int size) { - clearBufferIfnecessary(); - // Make sure fetcher is running if needed - restart(); + // Calculate out the capacity and refill threshold based on the user's random size preference + int shuffleListSize = Math.max(1, Integer.parseInt(Util.getPreferences(context).getString(Constants.PREFERENCES_KEY_RANDOM_SIZE, "20"))); + // ex: default 20 -> 50 + capacity = shuffleListSize * 5 / 2; + capacity = Math.min(500, capacity); - List result = new ArrayList(size); - synchronized (buffer) { - boolean removed = false; - while (!buffer.isEmpty() && result.size() < size) { - result.add(buffer.remove(buffer.size() - 1)); - removed = true; - } + // ex: default 20 -> 40 + refillThreshold = capacity * 4 / 5; + } - // Re-cache if anything is taken out - if(removed) { - FileUtil.serialize(context, buffer, CACHE_FILENAME); - } - } - Log.i(TAG, "Taking " + result.size() + " songs from shuffle play buffer. " + buffer.size() + " remaining."); - if(result.isEmpty()) { - awaitingResults = true; - } - return result; - } + public List get(int size) { + clearBufferIfnecessary(); + // Make sure fetcher is running if needed + restart(); - public void shutdown() { - executorService.shutdown(); - Util.getPreferences(context).unregisterOnSharedPreferenceChangeListener(listener); - } + List result = new ArrayList(size); + synchronized (buffer) { + boolean removed = false; + while (!buffer.isEmpty() && result.size() < size) { + result.add(buffer.remove(buffer.size() - 1)); + removed = true; + } - private void restart() { - synchronized(buffer) { - if(buffer.size() <= refillThreshold && lastCount != 0 && executorService.isShutdown()) { - executorService = Executors.newSingleThreadScheduledExecutor(); - executorService.scheduleWithFixedDelay(runnable, 0, 10, TimeUnit.SECONDS); - } - } - } + // Re-cache if anything is taken out + if(removed) { + FileUtil.serialize(context, buffer, CACHE_FILENAME); + } + } + Log.i(TAG, "Taking " + result.size() + " songs from shuffle play buffer. " + buffer.size() + " remaining."); + if(result.isEmpty()) { + awaitingResults = true; + } + return result; + } - private void refill() { - // Check if active server has changed. - clearBufferIfnecessary(); + public void shutdown() { + executorService.shutdown(); + Util.getPreferences(context).unregisterOnSharedPreferenceChangeListener(listener); + } - if (buffer != null && (buffer.size() > refillThreshold || (!Util.isNetworkConnected(context) && !Util.isOffline(context)) || lastCount == 0)) { - executorService.shutdown(); - return; - } + private void restart() { + synchronized(buffer) { + if(buffer.size() <= refillThreshold && lastCount != 0 && executorService.isShutdown()) { + executorService = Executors.newSingleThreadScheduledExecutor(); + executorService.scheduleWithFixedDelay(runnable, 0, 10, TimeUnit.SECONDS); + } + } + } - try { - MusicService service = MusicServiceFactory.getMusicService(context); - - // Get capacity based - int n = capacity - buffer.size(); - String folder = null; - if(!Util.isTagBrowsing(context)) { - folder = Util.getSelectedMusicFolderId(context); - } - MusicDirectory songs = service.getRandomSongs(n, folder, genre, startYear, endYear, context, null); + private void refill() { + // Check if active server has changed. + clearBufferIfnecessary(); - synchronized (buffer) { - lastCount = 0; - for(MusicDirectory.Entry entry: songs.getChildren()) { - if(!buffer.contains(entry)) { - buffer.add(entry); - lastCount++; - } - } - Log.i(TAG, "Refilled shuffle play buffer with " + lastCount + " songs."); + if (buffer != null && (buffer.size() > refillThreshold || (!Util.isNetworkConnected(context) && !Util.isOffline(context)) || lastCount == 0)) { + executorService.shutdown(); + return; + } - // Cache buffer - FileUtil.serialize(context, buffer, CACHE_FILENAME); - } - } catch (Exception x) { - // Give it one more try before quitting - if(lastCount != -2) { - lastCount = -2; - } else if(lastCount == -2) { - lastCount = 0; - } - Log.w(TAG, "Failed to refill shuffle play buffer.", x); - } - - if(awaitingResults) { - awaitingResults = false; - context.checkDownloads(); - } - } + try { + MusicService service = MusicServiceFactory.getMusicService(context); - private void clearBufferIfnecessary() { - synchronized (buffer) { - final SharedPreferences prefs = Util.getPreferences(context); - if (currentServer != Util.getActiveServer(context) - || !Util.equals(currentFolder, Util.getSelectedMusicFolderId(context)) - || (genre != null && !genre.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, ""))) - || (startYear != null && !startYear.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, ""))) - || (endYear != null && !endYear.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, "")))) { - lastCount = -1; - currentServer = Util.getActiveServer(context); - currentFolder = Util.getSelectedMusicFolderId(context); - genre = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, ""); - startYear = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, ""); - endYear = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, ""); - buffer.clear(); + // Get capacity based + int n = capacity - buffer.size(); + String folder = null; + if(!Util.isTagBrowsing(context)) { + folder = Util.getSelectedMusicFolderId(context); + } + MusicDirectory songs = service.getRandomSongs(n, folder, genre, startYear, endYear, context, null); - if(firstRun) { - ArrayList cacheList = FileUtil.deserialize(context, CACHE_FILENAME, ArrayList.class); - if(cacheList != null) { - buffer.addAll(cacheList); - } + synchronized (buffer) { + lastCount = 0; + for(MusicDirectory.Entry entry: songs.getChildren()) { + if(!buffer.contains(entry)) { + buffer.add(entry); + lastCount++; + } + } + Log.i(TAG, "Refilled shuffle play buffer with " + lastCount + " songs."); - listener = new SharedPreferences.OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { - clearBufferIfnecessary(); - restart(); - } - }; - prefs.registerOnSharedPreferenceChangeListener(listener); - firstRun = false; - } else { - // Clear cache - File file = new File(context.getCacheDir(), CACHE_FILENAME); - file.delete(); - } - } - } - } + // Cache buffer + FileUtil.serialize(context, buffer, CACHE_FILENAME); + } + } catch (Exception x) { + // Give it one more try before quitting + if(lastCount != -2) { + lastCount = -2; + } else if(lastCount == -2) { + lastCount = 0; + } + Log.w(TAG, "Failed to refill shuffle play buffer.", x); + } + + if(awaitingResults) { + awaitingResults = false; + context.checkDownloads(); + } + } + + private void clearBufferIfnecessary() { + synchronized (buffer) { + final SharedPreferences prefs = Util.getPreferences(context); + if (currentServer != Util.getActiveServer(context) + || !Util.equals(currentFolder, Util.getSelectedMusicFolderId(context)) + || (genre != null && !genre.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, ""))) + || (startYear != null && !startYear.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, ""))) + || (endYear != null && !endYear.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, "")))) { + lastCount = -1; + currentServer = Util.getActiveServer(context); + currentFolder = Util.getSelectedMusicFolderId(context); + genre = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, ""); + startYear = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, ""); + endYear = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, ""); + buffer.clear(); + + if(firstRun) { + ArrayList cacheList = FileUtil.deserialize(context, CACHE_FILENAME, ArrayList.class); + if(cacheList != null) { + buffer.addAll(cacheList); + } + + listener = new SharedPreferences.OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences prefs, String key) { + clearBufferIfnecessary(); + restart(); + } + }; + prefs.registerOnSharedPreferenceChangeListener(listener); + firstRun = false; + } else { + // Clear cache + File file = new File(context.getCacheDir(), CACHE_FILENAME); + file.delete(); + } + } + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/SilentBackgroundTask.java b/app/src/main/java/net/nullsum/audinaut/util/SilentBackgroundTask.java index 1947697..f37abc9 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/SilentBackgroundTask.java +++ b/app/src/main/java/net/nullsum/audinaut/util/SilentBackgroundTask.java @@ -30,13 +30,13 @@ public abstract class SilentBackgroundTask extends BackgroundTask { @Override public void execute() { - queue.offer(task = new Task()); + queue.offer(task = new Task()); } - @Override - protected void done(T result) { - // Don't do anything unless overriden - } + @Override + protected void done(T result) { + // Don't do anything unless overriden + } @Override public void updateProgress(int messageId) { diff --git a/app/src/main/java/net/nullsum/audinaut/util/SilentServiceTask.java b/app/src/main/java/net/nullsum/audinaut/util/SilentServiceTask.java index e0507f8..990d7fd 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/SilentServiceTask.java +++ b/app/src/main/java/net/nullsum/audinaut/util/SilentServiceTask.java @@ -1,20 +1,20 @@ /* - This file is part of Subsonic. + This file is part of Subsonic. - Subsonic 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. + Subsonic 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. - Subsonic 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. + Subsonic 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 Subsonic. If not, see . + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.util; @@ -25,17 +25,17 @@ import net.nullsum.audinaut.service.MusicService; import net.nullsum.audinaut.service.MusicServiceFactory; public abstract class SilentServiceTask extends SilentBackgroundTask { - protected MusicService musicService; + protected MusicService musicService; - public SilentServiceTask(Context context) { - super(context); - } + public SilentServiceTask(Context context) { + super(context); + } - @Override - protected T doInBackground() throws Throwable { - musicService = MusicServiceFactory.getMusicService(getContext()); - return doInBackground(musicService); - } + @Override + protected T doInBackground() throws Throwable { + musicService = MusicServiceFactory.getMusicService(getContext()); + return doInBackground(musicService); + } - protected abstract T doInBackground(MusicService musicService) throws Throwable; + protected abstract T doInBackground(MusicService musicService) throws Throwable; } diff --git a/app/src/main/java/net/nullsum/audinaut/util/SongDBHandler.java b/app/src/main/java/net/nullsum/audinaut/util/SongDBHandler.java index 34d60e3..b97892a 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/SongDBHandler.java +++ b/app/src/main/java/net/nullsum/audinaut/util/SongDBHandler.java @@ -1,16 +1,16 @@ /* - This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + This file is part of Subsonic. + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.util; @@ -29,235 +29,235 @@ import net.nullsum.audinaut.domain.MusicDirectory; import net.nullsum.audinaut.service.DownloadFile; public class SongDBHandler extends SQLiteOpenHelper { - private static final String TAG = SongDBHandler.class.getSimpleName(); - private static SongDBHandler dbHandler; + private static final String TAG = SongDBHandler.class.getSimpleName(); + private static SongDBHandler dbHandler; - private static final int DATABASE_VERSION = 2; - public static final String DATABASE_NAME = "SongsDB"; + private static final int DATABASE_VERSION = 2; + public static final String DATABASE_NAME = "SongsDB"; - public static final String TABLE_SONGS = "RegisteredSongs"; - public static final String SONGS_ID = "id"; - public static final String SONGS_SERVER_KEY = "serverKey"; - public static final String SONGS_SERVER_ID = "serverId"; - public static final String SONGS_COMPLETE_PATH = "completePath"; - public static final String SONGS_LAST_PLAYED = "lastPlayed"; - public static final String SONGS_LAST_COMPLETED = "lastCompleted"; + public static final String TABLE_SONGS = "RegisteredSongs"; + public static final String SONGS_ID = "id"; + public static final String SONGS_SERVER_KEY = "serverKey"; + public static final String SONGS_SERVER_ID = "serverId"; + public static final String SONGS_COMPLETE_PATH = "completePath"; + public static final String SONGS_LAST_PLAYED = "lastPlayed"; + public static final String SONGS_LAST_COMPLETED = "lastCompleted"; - private Context context; + private Context context; - private SongDBHandler(Context context) { - super(context, DATABASE_NAME, null, DATABASE_VERSION); - this.context = context; - } + private SongDBHandler(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + this.context = context; + } - @Override - public void onCreate(SQLiteDatabase db) { - db.execSQL("CREATE TABLE " + TABLE_SONGS + " ( " + - SONGS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + - SONGS_SERVER_KEY + " INTEGER NOT NULL, " + - SONGS_SERVER_ID + " TEXT NOT NULL, " + - SONGS_COMPLETE_PATH + " TEXT NOT NULL, " + - SONGS_LAST_PLAYED + " INTEGER, " + - SONGS_LAST_COMPLETED + " INTEGER, " + - "UNIQUE(" + SONGS_SERVER_KEY + ", " + SONGS_SERVER_ID + "))"); - } + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL("CREATE TABLE " + TABLE_SONGS + " ( " + + SONGS_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + + SONGS_SERVER_KEY + " INTEGER NOT NULL, " + + SONGS_SERVER_ID + " TEXT NOT NULL, " + + SONGS_COMPLETE_PATH + " TEXT NOT NULL, " + + SONGS_LAST_PLAYED + " INTEGER, " + + SONGS_LAST_COMPLETED + " INTEGER, " + + "UNIQUE(" + SONGS_SERVER_KEY + ", " + SONGS_SERVER_ID + "))"); + } - @Override - public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - db.execSQL("DROP TABLE IF EXISTS " + TABLE_SONGS); - this.onCreate(db); - } + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + db.execSQL("DROP TABLE IF EXISTS " + TABLE_SONGS); + this.onCreate(db); + } - public synchronized void addSong(DownloadFile downloadFile) { - addSong(Util.getMostRecentActiveServer(context), downloadFile); - } - public synchronized void addSong(int instance, DownloadFile downloadFile) { - SQLiteDatabase db = this.getWritableDatabase(); - addSong(db, instance, downloadFile); - db.close(); - } - protected synchronized void addSong(SQLiteDatabase db, DownloadFile downloadFile) { - addSong(db, Util.getMostRecentActiveServer(context), downloadFile); - } - protected synchronized void addSong(SQLiteDatabase db, int instance, DownloadFile downloadFile) { - addSong(db, instance, downloadFile.getSong().getId(), downloadFile.getSaveFile().getAbsolutePath()); - } + public synchronized void addSong(DownloadFile downloadFile) { + addSong(Util.getMostRecentActiveServer(context), downloadFile); + } + public synchronized void addSong(int instance, DownloadFile downloadFile) { + SQLiteDatabase db = this.getWritableDatabase(); + addSong(db, instance, downloadFile); + db.close(); + } + protected synchronized void addSong(SQLiteDatabase db, DownloadFile downloadFile) { + addSong(db, Util.getMostRecentActiveServer(context), downloadFile); + } + protected synchronized void addSong(SQLiteDatabase db, int instance, DownloadFile downloadFile) { + addSong(db, instance, downloadFile.getSong().getId(), downloadFile.getSaveFile().getAbsolutePath()); + } - protected synchronized void addSong(SQLiteDatabase db, String id, String absolutePath) { - addSong(db, Util.getMostRecentActiveServer(context), id, absolutePath); - } - protected synchronized void addSong(SQLiteDatabase db, int instance, String id, String absolutePath) { - addSongImpl(db, Util.getRestUrlHash(context, instance), id, absolutePath); - } - protected synchronized void addSongImpl(SQLiteDatabase db, int serverKey, String id, String absolutePath) { - ContentValues values = new ContentValues(); - values.put(SONGS_SERVER_KEY, serverKey); - values.put(SONGS_SERVER_ID, id); - values.put(SONGS_COMPLETE_PATH, absolutePath); + protected synchronized void addSong(SQLiteDatabase db, String id, String absolutePath) { + addSong(db, Util.getMostRecentActiveServer(context), id, absolutePath); + } + protected synchronized void addSong(SQLiteDatabase db, int instance, String id, String absolutePath) { + addSongImpl(db, Util.getRestUrlHash(context, instance), id, absolutePath); + } + protected synchronized void addSongImpl(SQLiteDatabase db, int serverKey, String id, String absolutePath) { + ContentValues values = new ContentValues(); + values.put(SONGS_SERVER_KEY, serverKey); + values.put(SONGS_SERVER_ID, id); + values.put(SONGS_COMPLETE_PATH, absolutePath); - db.insertWithOnConflict(TABLE_SONGS, null, values, SQLiteDatabase.CONFLICT_IGNORE); - } + db.insertWithOnConflict(TABLE_SONGS, null, values, SQLiteDatabase.CONFLICT_IGNORE); + } - public synchronized void addSongs(int instance, List entries) { - SQLiteDatabase db = this.getWritableDatabase(); + public synchronized void addSongs(int instance, List entries) { + SQLiteDatabase db = this.getWritableDatabase(); - List> pairs = new ArrayList<>(); - for(MusicDirectory.Entry entry: entries) { - pairs.add(new Pair<>(entry.getId(), FileUtil.getSongFile(context, entry).getAbsolutePath())); - } - addSongs(db, instance, pairs); + List> pairs = new ArrayList<>(); + for(MusicDirectory.Entry entry: entries) { + pairs.add(new Pair<>(entry.getId(), FileUtil.getSongFile(context, entry).getAbsolutePath())); + } + addSongs(db, instance, pairs); - db.close(); - } - public synchronized void addSongs(SQLiteDatabase db, int instance, List> entries) { - addSongsImpl(db, Util.getRestUrlHash(context, instance), entries); - } - protected synchronized void addSongsImpl(SQLiteDatabase db, int serverKey, List> entries) { - db.beginTransaction(); - try { - for (Pair entry : entries) { - ContentValues values = new ContentValues(); - values.put(SONGS_SERVER_KEY, serverKey); - values.put(SONGS_SERVER_ID, entry.getFirst()); - values.put(SONGS_COMPLETE_PATH, entry.getSecond()); - // Util.sleepQuietly(10000); + db.close(); + } + public synchronized void addSongs(SQLiteDatabase db, int instance, List> entries) { + addSongsImpl(db, Util.getRestUrlHash(context, instance), entries); + } + protected synchronized void addSongsImpl(SQLiteDatabase db, int serverKey, List> entries) { + db.beginTransaction(); + try { + for (Pair entry : entries) { + ContentValues values = new ContentValues(); + values.put(SONGS_SERVER_KEY, serverKey); + values.put(SONGS_SERVER_ID, entry.getFirst()); + values.put(SONGS_COMPLETE_PATH, entry.getSecond()); + // Util.sleepQuietly(10000); - db.insertWithOnConflict(TABLE_SONGS, null, values, SQLiteDatabase.CONFLICT_IGNORE); - } + db.insertWithOnConflict(TABLE_SONGS, null, values, SQLiteDatabase.CONFLICT_IGNORE); + } - db.setTransactionSuccessful(); - } catch(Exception e) {} + db.setTransactionSuccessful(); + } catch(Exception e) {} - db.endTransaction(); - } + db.endTransaction(); + } - public synchronized void setSongPlayed(DownloadFile downloadFile, boolean submission) { - // TODO: In case of offline want to update all matches - Pair pair = getOnlineSongId(downloadFile); - if(pair == null) { - return; - } - int serverKey = pair.getFirst(); - String id = pair.getSecond(); + public synchronized void setSongPlayed(DownloadFile downloadFile, boolean submission) { + // TODO: In case of offline want to update all matches + Pair pair = getOnlineSongId(downloadFile); + if(pair == null) { + return; + } + int serverKey = pair.getFirst(); + String id = pair.getSecond(); - // Open and make sure song is in db - SQLiteDatabase db = this.getWritableDatabase(); - addSongImpl(db, serverKey, id, downloadFile.getSaveFile().getAbsolutePath()); + // Open and make sure song is in db + SQLiteDatabase db = this.getWritableDatabase(); + addSongImpl(db, serverKey, id, downloadFile.getSaveFile().getAbsolutePath()); - // Update song's last played - ContentValues values = new ContentValues(); - values.put(submission ? SONGS_LAST_COMPLETED : SONGS_LAST_PLAYED, System.currentTimeMillis()); - db.update(TABLE_SONGS, values, SONGS_SERVER_KEY + " = ? AND " + SONGS_SERVER_ID + " = ?", new String[]{Integer.toString(serverKey), id}); - db.close(); - } + // Update song's last played + ContentValues values = new ContentValues(); + values.put(submission ? SONGS_LAST_COMPLETED : SONGS_LAST_PLAYED, System.currentTimeMillis()); + db.update(TABLE_SONGS, values, SONGS_SERVER_KEY + " = ? AND " + SONGS_SERVER_ID + " = ?", new String[]{Integer.toString(serverKey), id}); + db.close(); + } - public boolean hasBeenPlayed(MusicDirectory.Entry entry) { - Long[] lastPlayed = getLastPlayed(entry); - return lastPlayed != null && lastPlayed[0] != null && lastPlayed[0] > 0; - } - public boolean hasBeenCompleted(MusicDirectory.Entry entry) { - Long[] lastPlayed = getLastPlayed(entry); - return lastPlayed != null && lastPlayed[1] != null && lastPlayed[1] > 0; - } - public synchronized Long[] getLastPlayed(MusicDirectory.Entry entry) { - return getLastPlayed(getOnlineSongId(entry)); - } - protected synchronized Long[] getLastPlayed(Pair pair) { - if(pair == null) { - return null; - } else { - return getLastPlayed(pair.getFirst(), pair.getSecond()); - } - } - public synchronized Long[] getLastPlayed(int serverKey, String id) { - SQLiteDatabase db = this.getReadableDatabase(); + public boolean hasBeenPlayed(MusicDirectory.Entry entry) { + Long[] lastPlayed = getLastPlayed(entry); + return lastPlayed != null && lastPlayed[0] != null && lastPlayed[0] > 0; + } + public boolean hasBeenCompleted(MusicDirectory.Entry entry) { + Long[] lastPlayed = getLastPlayed(entry); + return lastPlayed != null && lastPlayed[1] != null && lastPlayed[1] > 0; + } + public synchronized Long[] getLastPlayed(MusicDirectory.Entry entry) { + return getLastPlayed(getOnlineSongId(entry)); + } + protected synchronized Long[] getLastPlayed(Pair pair) { + if(pair == null) { + return null; + } else { + return getLastPlayed(pair.getFirst(), pair.getSecond()); + } + } + public synchronized Long[] getLastPlayed(int serverKey, String id) { + SQLiteDatabase db = this.getReadableDatabase(); - String[] columns = {SONGS_LAST_PLAYED, SONGS_LAST_COMPLETED}; - Cursor cursor = db.query(TABLE_SONGS, columns, SONGS_SERVER_KEY + " = ? AND " + SONGS_SERVER_ID + " = ?", new String[]{Integer.toString(serverKey), id}, null, null, null, null); + String[] columns = {SONGS_LAST_PLAYED, SONGS_LAST_COMPLETED}; + Cursor cursor = db.query(TABLE_SONGS, columns, SONGS_SERVER_KEY + " = ? AND " + SONGS_SERVER_ID + " = ?", new String[]{Integer.toString(serverKey), id}, null, null, null, null); - try { - cursor.moveToFirst(); + try { + cursor.moveToFirst(); - Long[] dates = new Long[2]; - dates[0] = cursor.getLong(0); - dates[1] = cursor.getLong(1); - return dates; - } catch(Exception e) { - return null; - } - finally { - cursor.close(); - db.close(); - } - } - - public synchronized Pair getOnlineSongId(MusicDirectory.Entry entry) { - return getOnlineSongId(Util.getRestUrlHash(context), entry.getId(), FileUtil.getSongFile(context, entry).getAbsolutePath(), Util.isOffline(context) ? false : true); - } - public synchronized Pair getOnlineSongId(DownloadFile downloadFile) { - return getOnlineSongId(Util.getRestUrlHash(context), downloadFile.getSong().getId(), downloadFile.getSaveFile().getAbsolutePath(), Util.isOffline(context) ? false : true); - } - - public synchronized Pair getOnlineSongId(int serverKey, MusicDirectory.Entry entry) { - return getOnlineSongId(serverKey, new DownloadFile(context, entry, true)); - } - public synchronized Pair getOnlineSongId(int serverKey, DownloadFile downloadFile) { - return getOnlineSongId(serverKey, downloadFile.getSong().getId(), downloadFile.getSaveFile().getAbsolutePath(), true); - } - public synchronized Pair getOnlineSongId(int serverKey, String id, String savePath, boolean requireServerKey) { - SharedPreferences prefs = Util.getPreferences(context); - String cacheLocn = prefs.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null); - if(cacheLocn != null && id.indexOf(cacheLocn) != -1) { - if(requireServerKey) { - return getIdFromPath(serverKey, savePath); - } else { - return getIdFromPath(savePath); - } - } else { - return new Pair<>(serverKey, id); - } - } - - public synchronized Pair getIdFromPath(String path) { - SQLiteDatabase db = this.getReadableDatabase(); - - String[] columns = {SONGS_SERVER_KEY, SONGS_SERVER_ID}; - Cursor cursor = db.query(TABLE_SONGS, columns, SONGS_COMPLETE_PATH + " = ?", new String[] { path }, null, null, SONGS_LAST_PLAYED + " DESC", null); - - try { - cursor.moveToFirst(); - return new Pair(cursor.getInt(0), cursor.getString(1)); - } catch(Exception e) { - return null; - } - finally { + Long[] dates = new Long[2]; + dates[0] = cursor.getLong(0); + dates[1] = cursor.getLong(1); + return dates; + } catch(Exception e) { + return null; + } + finally { cursor.close(); - db.close(); - } - } - public synchronized Pair getIdFromPath(int serverKey, String path) { - SQLiteDatabase db = this.getReadableDatabase(); + db.close(); + } + } - String[] columns = {SONGS_SERVER_KEY, SONGS_SERVER_ID}; - Cursor cursor = db.query(TABLE_SONGS, columns, SONGS_SERVER_KEY + " = ? AND " + SONGS_COMPLETE_PATH + " = ?", new String[] {Integer.toString(serverKey), path }, null, null, null, null); + public synchronized Pair getOnlineSongId(MusicDirectory.Entry entry) { + return getOnlineSongId(Util.getRestUrlHash(context), entry.getId(), FileUtil.getSongFile(context, entry).getAbsolutePath(), Util.isOffline(context) ? false : true); + } + public synchronized Pair getOnlineSongId(DownloadFile downloadFile) { + return getOnlineSongId(Util.getRestUrlHash(context), downloadFile.getSong().getId(), downloadFile.getSaveFile().getAbsolutePath(), Util.isOffline(context) ? false : true); + } - try { - cursor.moveToFirst(); - return new Pair(cursor.getInt(0), cursor.getString(1)); - } catch(Exception e) { - return null; - } - finally { + public synchronized Pair getOnlineSongId(int serverKey, MusicDirectory.Entry entry) { + return getOnlineSongId(serverKey, new DownloadFile(context, entry, true)); + } + public synchronized Pair getOnlineSongId(int serverKey, DownloadFile downloadFile) { + return getOnlineSongId(serverKey, downloadFile.getSong().getId(), downloadFile.getSaveFile().getAbsolutePath(), true); + } + public synchronized Pair getOnlineSongId(int serverKey, String id, String savePath, boolean requireServerKey) { + SharedPreferences prefs = Util.getPreferences(context); + String cacheLocn = prefs.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, null); + if(cacheLocn != null && id.indexOf(cacheLocn) != -1) { + if(requireServerKey) { + return getIdFromPath(serverKey, savePath); + } else { + return getIdFromPath(savePath); + } + } else { + return new Pair<>(serverKey, id); + } + } + + public synchronized Pair getIdFromPath(String path) { + SQLiteDatabase db = this.getReadableDatabase(); + + String[] columns = {SONGS_SERVER_KEY, SONGS_SERVER_ID}; + Cursor cursor = db.query(TABLE_SONGS, columns, SONGS_COMPLETE_PATH + " = ?", new String[] { path }, null, null, SONGS_LAST_PLAYED + " DESC", null); + + try { + cursor.moveToFirst(); + return new Pair(cursor.getInt(0), cursor.getString(1)); + } catch(Exception e) { + return null; + } + finally { cursor.close(); - db.close(); - } - } + db.close(); + } + } + public synchronized Pair getIdFromPath(int serverKey, String path) { + SQLiteDatabase db = this.getReadableDatabase(); - public static SongDBHandler getHandler(Context context) { - if(dbHandler == null) { - dbHandler = new SongDBHandler(context); - } + String[] columns = {SONGS_SERVER_KEY, SONGS_SERVER_ID}; + Cursor cursor = db.query(TABLE_SONGS, columns, SONGS_SERVER_KEY + " = ? AND " + SONGS_COMPLETE_PATH + " = ?", new String[] {Integer.toString(serverKey), path }, null, null, null, null); - return dbHandler; - } + try { + cursor.moveToFirst(); + return new Pair(cursor.getInt(0), cursor.getString(1)); + } catch(Exception e) { + return null; + } + finally { + cursor.close(); + db.close(); + } + } + + public static SongDBHandler getHandler(Context context) { + if(dbHandler == null) { + dbHandler = new SongDBHandler(context); + } + + return dbHandler; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/SyncUtil.java b/app/src/main/java/net/nullsum/audinaut/util/SyncUtil.java index b06d6ef..432fd8d 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/SyncUtil.java +++ b/app/src/main/java/net/nullsum/audinaut/util/SyncUtil.java @@ -18,139 +18,139 @@ import net.nullsum.audinaut.activity.SubsonicFragmentActivity; * Created by Scott on 11/24/13. */ public final class SyncUtil { - private static String TAG = SyncUtil.class.getSimpleName(); - private static ArrayList syncedPlaylists; - private static String url; + private static String TAG = SyncUtil.class.getSimpleName(); + private static ArrayList syncedPlaylists; + private static String url; - private static void checkRestURL(Context context) { - int instance = Util.getActiveServer(context); - String newURL = Util.getRestUrl(context, null, instance, false); - if(url == null || !url.equals(newURL)) { - syncedPlaylists = null; - url = newURL; - } - } + private static void checkRestURL(Context context) { + int instance = Util.getActiveServer(context); + String newURL = Util.getRestUrl(context, null, instance, false); + if(url == null || !url.equals(newURL)) { + syncedPlaylists = null; + url = newURL; + } + } - // Playlist sync - public static boolean isSyncedPlaylist(Context context, String playlistId) { - checkRestURL(context); - if(syncedPlaylists == null) { - syncedPlaylists = getSyncedPlaylists(context); - } - return syncedPlaylists.contains(new SyncSet(playlistId)); - } - public static ArrayList getSyncedPlaylists(Context context) { - return getSyncedPlaylists(context, Util.getActiveServer(context)); - } - public static ArrayList getSyncedPlaylists(Context context, int instance) { - String syncFile = getPlaylistSyncFile(context, instance); - ArrayList playlists = FileUtil.deserializeCompressed(context, syncFile, ArrayList.class); - if(playlists == null) { - playlists = new ArrayList(); + // Playlist sync + public static boolean isSyncedPlaylist(Context context, String playlistId) { + checkRestURL(context); + if(syncedPlaylists == null) { + syncedPlaylists = getSyncedPlaylists(context); + } + return syncedPlaylists.contains(new SyncSet(playlistId)); + } + public static ArrayList getSyncedPlaylists(Context context) { + return getSyncedPlaylists(context, Util.getActiveServer(context)); + } + public static ArrayList getSyncedPlaylists(Context context, int instance) { + String syncFile = getPlaylistSyncFile(context, instance); + ArrayList playlists = FileUtil.deserializeCompressed(context, syncFile, ArrayList.class); + if(playlists == null) { + playlists = new ArrayList(); - // Try to convert old style into new style - ArrayList oldPlaylists = FileUtil.deserialize(context, syncFile, ArrayList.class); - // If exists, time to convert! - if(oldPlaylists != null) { - for(String id: oldPlaylists) { - playlists.add(new SyncSet(id)); - } + // Try to convert old style into new style + ArrayList oldPlaylists = FileUtil.deserialize(context, syncFile, ArrayList.class); + // If exists, time to convert! + if(oldPlaylists != null) { + for(String id: oldPlaylists) { + playlists.add(new SyncSet(id)); + } - FileUtil.serializeCompressed(context, playlists, syncFile); - } - } - return playlists; - } - public static void setSyncedPlaylists(Context context, int instance, ArrayList playlists) { - FileUtil.serializeCompressed(context, playlists, getPlaylistSyncFile(context, instance)); - } - public static void addSyncedPlaylist(Context context, String playlistId) { - String playlistFile = getPlaylistSyncFile(context); - ArrayList playlists = getSyncedPlaylists(context); - SyncSet set = new SyncSet(playlistId); - if(!playlists.contains(set)) { - playlists.add(set); - } - FileUtil.serializeCompressed(context, playlists, playlistFile); - syncedPlaylists = playlists; - } - public static void removeSyncedPlaylist(Context context, String playlistId) { - int instance = Util.getActiveServer(context); - removeSyncedPlaylist(context, playlistId, instance); - } - public static void removeSyncedPlaylist(Context context, String playlistId, int instance) { - String playlistFile = getPlaylistSyncFile(context, instance); - ArrayList playlists = getSyncedPlaylists(context, instance); - SyncSet set = new SyncSet(playlistId); - if(playlists.contains(set)) { - playlists.remove(set); - FileUtil.serializeCompressed(context, playlists, playlistFile); - syncedPlaylists = playlists; - } - } - public static String getPlaylistSyncFile(Context context) { - int instance = Util.getActiveServer(context); - return getPlaylistSyncFile(context, instance); - } - public static String getPlaylistSyncFile(Context context, int instance) { - return "sync-playlist-" + (Util.getRestUrl(context, null, instance, false)).hashCode() + ".ser"; - } + FileUtil.serializeCompressed(context, playlists, syncFile); + } + } + return playlists; + } + public static void setSyncedPlaylists(Context context, int instance, ArrayList playlists) { + FileUtil.serializeCompressed(context, playlists, getPlaylistSyncFile(context, instance)); + } + public static void addSyncedPlaylist(Context context, String playlistId) { + String playlistFile = getPlaylistSyncFile(context); + ArrayList playlists = getSyncedPlaylists(context); + SyncSet set = new SyncSet(playlistId); + if(!playlists.contains(set)) { + playlists.add(set); + } + FileUtil.serializeCompressed(context, playlists, playlistFile); + syncedPlaylists = playlists; + } + public static void removeSyncedPlaylist(Context context, String playlistId) { + int instance = Util.getActiveServer(context); + removeSyncedPlaylist(context, playlistId, instance); + } + public static void removeSyncedPlaylist(Context context, String playlistId, int instance) { + String playlistFile = getPlaylistSyncFile(context, instance); + ArrayList playlists = getSyncedPlaylists(context, instance); + SyncSet set = new SyncSet(playlistId); + if(playlists.contains(set)) { + playlists.remove(set); + FileUtil.serializeCompressed(context, playlists, playlistFile); + syncedPlaylists = playlists; + } + } + public static String getPlaylistSyncFile(Context context) { + int instance = Util.getActiveServer(context); + return getPlaylistSyncFile(context, instance); + } + public static String getPlaylistSyncFile(Context context, int instance) { + return "sync-playlist-" + (Util.getRestUrl(context, null, instance, false)).hashCode() + ".ser"; + } - // Most Recently Added - public static ArrayList getSyncedMostRecent(Context context, int instance) { - ArrayList list = FileUtil.deserialize(context, getMostRecentSyncFile(context, instance), ArrayList.class); - if(list == null) { - list = new ArrayList(); - } - return list; - } - public static void removeMostRecentSyncFiles(Context context) { - int total = Util.getServerCount(context); - for(int i = 0; i < total; i++) { - File file = new File(context.getCacheDir(), getMostRecentSyncFile(context, i)); - file.delete(); - } - } - public static String getMostRecentSyncFile(Context context, int instance) { - return "sync-most_recent-" + (Util.getRestUrl(context, null, instance, false)).hashCode() + ".ser"; - } + // Most Recently Added + public static ArrayList getSyncedMostRecent(Context context, int instance) { + ArrayList list = FileUtil.deserialize(context, getMostRecentSyncFile(context, instance), ArrayList.class); + if(list == null) { + list = new ArrayList(); + } + return list; + } + public static void removeMostRecentSyncFiles(Context context) { + int total = Util.getServerCount(context); + for(int i = 0; i < total; i++) { + File file = new File(context.getCacheDir(), getMostRecentSyncFile(context, i)); + file.delete(); + } + } + public static String getMostRecentSyncFile(Context context, int instance) { + return "sync-most_recent-" + (Util.getRestUrl(context, null, instance, false)).hashCode() + ".ser"; + } - public static String joinNames(List names) { - StringBuilder builder = new StringBuilder(); - for (String val : names) { - builder.append(val).append(", "); - } - builder.setLength(builder.length() - 2); - return builder.toString(); - } + public static String joinNames(List names) { + StringBuilder builder = new StringBuilder(); + for (String val : names) { + builder.append(val).append(", "); + } + builder.setLength(builder.length() - 2); + return builder.toString(); + } - public static class SyncSet implements Serializable { - public String id; - public List synced; + public static class SyncSet implements Serializable { + public String id; + public List synced; - protected SyncSet() { + protected SyncSet() { - } - public SyncSet(String id) { - this.id = id; - } - public SyncSet(String id, List synced) { - this.id = id; - this.synced = synced; - } + } + public SyncSet(String id) { + this.id = id; + } + public SyncSet(String id, List synced) { + this.id = id; + this.synced = synced; + } - @Override - public boolean equals(Object obj) { - if(obj instanceof SyncSet) { - return this.id.equals(((SyncSet)obj).id); - } else { - return false; - } - } + @Override + public boolean equals(Object obj) { + if(obj instanceof SyncSet) { + return this.id.equals(((SyncSet)obj).id); + } else { + return false; + } + } - @Override - public int hashCode() { - return id.hashCode(); - } - } + @Override + public int hashCode() { + return id.hashCode(); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/TabBackgroundTask.java b/app/src/main/java/net/nullsum/audinaut/util/TabBackgroundTask.java index 2338829..91ea875 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/TabBackgroundTask.java +++ b/app/src/main/java/net/nullsum/audinaut/util/TabBackgroundTask.java @@ -19,22 +19,22 @@ public abstract class TabBackgroundTask extends BackgroundTask { public void execute() { tabFragment.setProgressVisible(true); - queue.offer(task = new Task() { - @Override - public void onDone(T result) { - tabFragment.setProgressVisible(false); - done(result); - } + queue.offer(task = new Task() { + @Override + public void onDone(T result) { + tabFragment.setProgressVisible(false); + done(result); + } - @Override - public void onError(Throwable t) { - tabFragment.setProgressVisible(false); - error(t); - } - }); + @Override + public void onError(Throwable t) { + tabFragment.setProgressVisible(false); + error(t); + } + }); } - @Override + @Override public boolean isCancelled() { return !tabFragment.isAdded() || cancelled.get(); } diff --git a/app/src/main/java/net/nullsum/audinaut/util/ThemeUtil.java b/app/src/main/java/net/nullsum/audinaut/util/ThemeUtil.java index c854567..06c996d 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/ThemeUtil.java +++ b/app/src/main/java/net/nullsum/audinaut/util/ThemeUtil.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2016 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2016 (C) Scott Jackson */ package net.nullsum.audinaut.util; @@ -26,73 +26,73 @@ import net.nullsum.audinaut.activity.SettingsActivity; import net.nullsum.audinaut.activity.SubsonicFragmentActivity; public final class ThemeUtil { - public static final String THEME_DARK = "dark"; - public static final String THEME_BLACK = "black"; - public static final String THEME_LIGHT = "light"; - public static final String THEME_DAY_NIGHT = "day/night"; - public static final String THEME_DAY_BLACK_NIGHT = "day/black"; + public static final String THEME_DARK = "dark"; + public static final String THEME_BLACK = "black"; + public static final String THEME_LIGHT = "light"; + public static final String THEME_DAY_NIGHT = "day/night"; + public static final String THEME_DAY_BLACK_NIGHT = "day/black"; - public static String getTheme(Context context) { - SharedPreferences prefs = Util.getPreferences(context); - String theme = prefs.getString(Constants.PREFERENCES_KEY_THEME, null); + public static String getTheme(Context context) { + SharedPreferences prefs = Util.getPreferences(context); + String theme = prefs.getString(Constants.PREFERENCES_KEY_THEME, null); - if(THEME_DAY_NIGHT.equals(theme)) { - int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; - if(currentNightMode == Configuration.UI_MODE_NIGHT_YES) { - theme = THEME_DARK; - } else { - theme = THEME_LIGHT; - } - } else if(THEME_DAY_BLACK_NIGHT.equals(theme)) { - int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; - if(currentNightMode == Configuration.UI_MODE_NIGHT_YES) { - theme = THEME_BLACK; - } else { - theme = THEME_LIGHT; - } - } + if(THEME_DAY_NIGHT.equals(theme)) { + int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; + if(currentNightMode == Configuration.UI_MODE_NIGHT_YES) { + theme = THEME_DARK; + } else { + theme = THEME_LIGHT; + } + } else if(THEME_DAY_BLACK_NIGHT.equals(theme)) { + int currentNightMode = context.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; + if(currentNightMode == Configuration.UI_MODE_NIGHT_YES) { + theme = THEME_BLACK; + } else { + theme = THEME_LIGHT; + } + } - return theme; - } - public static int getThemeRes(Context context) { - return getThemeRes(context, getTheme(context)); - } - public static int getThemeRes(Context context, String theme) { - if(context instanceof SubsonicFragmentActivity || context instanceof SettingsActivity) { - if(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true)) { - if (THEME_DARK.equals(theme)) { - return R.style.Theme_Audinaut_Dark_No_Actionbar; - } else if (THEME_BLACK.equals(theme)) { - return R.style.Theme_Audinaut_Black_No_Actionbar; - } else { - return R.style.Theme_Audinaut_Light_No_Actionbar; - } - } else { - if (THEME_DARK.equals(theme)) { - return R.style.Theme_Audinaut_Dark_No_Color; - } else if (THEME_BLACK.equals(theme)) { - return R.style.Theme_Audinaut_Black_No_Color; - } else { - return R.style.Theme_Audinaut_Light_No_Color; - } - } - } else { - if (THEME_DARK.equals(theme)) { - return R.style.Theme_Audinaut_Dark; - } else if (THEME_BLACK.equals(theme)) { - return R.style.Theme_Audinaut_Black; - } else { - return R.style.Theme_Audinaut_Light; - } - } - } - public static void setTheme(Context context, String theme) { - SharedPreferences.Editor editor = Util.getPreferences(context).edit(); - editor.putString(Constants.PREFERENCES_KEY_THEME, theme); - editor.apply(); - } + return theme; + } + public static int getThemeRes(Context context) { + return getThemeRes(context, getTheme(context)); + } + public static int getThemeRes(Context context, String theme) { + if(context instanceof SubsonicFragmentActivity || context instanceof SettingsActivity) { + if(Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_COLOR_ACTION_BAR, true)) { + if (THEME_DARK.equals(theme)) { + return R.style.Theme_Audinaut_Dark_No_Actionbar; + } else if (THEME_BLACK.equals(theme)) { + return R.style.Theme_Audinaut_Black_No_Actionbar; + } else { + return R.style.Theme_Audinaut_Light_No_Actionbar; + } + } else { + if (THEME_DARK.equals(theme)) { + return R.style.Theme_Audinaut_Dark_No_Color; + } else if (THEME_BLACK.equals(theme)) { + return R.style.Theme_Audinaut_Black_No_Color; + } else { + return R.style.Theme_Audinaut_Light_No_Color; + } + } + } else { + if (THEME_DARK.equals(theme)) { + return R.style.Theme_Audinaut_Dark; + } else if (THEME_BLACK.equals(theme)) { + return R.style.Theme_Audinaut_Black; + } else { + return R.style.Theme_Audinaut_Light; + } + } + } + public static void setTheme(Context context, String theme) { + SharedPreferences.Editor editor = Util.getPreferences(context).edit(); + editor.putString(Constants.PREFERENCES_KEY_THEME, theme); + editor.apply(); + } - public static void applyTheme(Context context, String theme) { - context.setTheme(getThemeRes(context, theme)); - } + public static void applyTheme(Context context, String theme) { + context.setTheme(getThemeRes(context, theme)); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/UpdateHelper.java b/app/src/main/java/net/nullsum/audinaut/util/UpdateHelper.java index 4137710..606b288 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/UpdateHelper.java +++ b/app/src/main/java/net/nullsum/audinaut/util/UpdateHelper.java @@ -1,20 +1,20 @@ /* - This file is part of Subsonic. + This file is part of Subsonic. - Subsonic 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. + Subsonic 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. - Subsonic 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. + Subsonic 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 Subsonic. If not, see . + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.util; @@ -43,50 +43,50 @@ import net.nullsum.audinaut.service.OfflineException; import net.nullsum.audinaut.view.UpdateView; public final class UpdateHelper { - private static final String TAG = UpdateHelper.class.getSimpleName(); + private static final String TAG = UpdateHelper.class.getSimpleName(); - public static abstract class EntryInstanceUpdater { - private Entry entry; - protected int metadataUpdate = DownloadService.METADATA_UPDATED_ALL; + public static abstract class EntryInstanceUpdater { + private Entry entry; + protected int metadataUpdate = DownloadService.METADATA_UPDATED_ALL; - public EntryInstanceUpdater(Entry entry) { - this.entry = entry; - } - public EntryInstanceUpdater(Entry entry, int metadataUpdate) { - this.entry = entry; - this.metadataUpdate = metadataUpdate; - } + public EntryInstanceUpdater(Entry entry) { + this.entry = entry; + } + public EntryInstanceUpdater(Entry entry, int metadataUpdate) { + this.entry = entry; + this.metadataUpdate = metadataUpdate; + } - public abstract void update(Entry found); + public abstract void update(Entry found); - public void execute() { - DownloadService downloadService = DownloadService.getInstance(); - if(downloadService != null && !entry.isDirectory()) { - boolean serializeChanges = false; - List downloadFiles = downloadService.getDownloads(); - DownloadFile currentPlaying = downloadService.getCurrentPlaying(); + public void execute() { + DownloadService downloadService = DownloadService.getInstance(); + if(downloadService != null && !entry.isDirectory()) { + boolean serializeChanges = false; + List downloadFiles = downloadService.getDownloads(); + DownloadFile currentPlaying = downloadService.getCurrentPlaying(); - for(DownloadFile file: downloadFiles) { - Entry check = file.getSong(); - if(entry.getId().equals(check.getId())) { - update(check); - serializeChanges = true; + for(DownloadFile file: downloadFiles) { + Entry check = file.getSong(); + if(entry.getId().equals(check.getId())) { + update(check); + serializeChanges = true; - if(currentPlaying != null && currentPlaying.getSong() != null && currentPlaying.getSong().getId().equals(entry.getId())) { - downloadService.onMetadataUpdate(metadataUpdate); - } - } - } + if(currentPlaying != null && currentPlaying.getSong() != null && currentPlaying.getSong().getId().equals(entry.getId())) { + downloadService.onMetadataUpdate(metadataUpdate); + } + } + } - if(serializeChanges) { - downloadService.serializeQueue(); - } - } + if(serializeChanges) { + downloadService.serializeQueue(); + } + } - Entry find = UpdateView.findEntry(entry); - if(find != null) { - update(find); - } - } - } + Entry find = UpdateView.findEntry(entry); + if(find != null) { + update(find); + } + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/UserUtil.java b/app/src/main/java/net/nullsum/audinaut/util/UserUtil.java index 0fa5331..7e0b332 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/UserUtil.java +++ b/app/src/main/java/net/nullsum/audinaut/util/UserUtil.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.util; @@ -43,80 +43,80 @@ import net.nullsum.audinaut.adapter.SettingsAdapter; import net.nullsum.audinaut.view.UpdateView; public final class UserUtil { - private static final String TAG = UserUtil.class.getSimpleName(); - private static final long MIN_VERIFY_DURATION = 1000L * 60L * 60L; - - private static int instance = -1; - private static int instanceHash = -1; - private static User currentUser; - private static long lastVerifiedTime = 0; + private static final String TAG = UserUtil.class.getSimpleName(); + private static final long MIN_VERIFY_DURATION = 1000L * 60L * 60L; - public static void refreshCurrentUser(Context context, boolean forceRefresh) { - refreshCurrentUser(context, forceRefresh, false); - } - public static void refreshCurrentUser(Context context, boolean forceRefresh, boolean unAuth) { - currentUser = null; - if(unAuth) { - lastVerifiedTime = 0; - } - seedCurrentUser(context, forceRefresh); - } + private static int instance = -1; + private static int instanceHash = -1; + private static User currentUser; + private static long lastVerifiedTime = 0; - public static void seedCurrentUser(Context context) { - seedCurrentUser(context, false); - } - public static void seedCurrentUser(final Context context, final boolean refresh) { - // Only try to seed if online - if(Util.isOffline(context)) { - currentUser = null; - return; - } - - final int instance = Util.getActiveServer(context); - final int instanceHash = (instance == 0) ? 0 : Util.getRestUrl(context, null).hashCode(); - if(UserUtil.instance == instance && UserUtil.instanceHash == instanceHash && currentUser != null) { - return; - } else { - UserUtil.instance = instance; - UserUtil.instanceHash = instanceHash; - } + public static void refreshCurrentUser(Context context, boolean forceRefresh) { + refreshCurrentUser(context, forceRefresh, false); + } + public static void refreshCurrentUser(Context context, boolean forceRefresh, boolean unAuth) { + currentUser = null; + if(unAuth) { + lastVerifiedTime = 0; + } + seedCurrentUser(context, forceRefresh); + } - new SilentBackgroundTask(context) { - @Override - protected Void doInBackground() throws Throwable { - currentUser = MusicServiceFactory.getMusicService(context).getUser(refresh, getCurrentUsername(context, instance), context, null); + public static void seedCurrentUser(Context context) { + seedCurrentUser(context, false); + } + public static void seedCurrentUser(final Context context, final boolean refresh) { + // Only try to seed if online + if(Util.isOffline(context)) { + currentUser = null; + return; + } - // If running, redo cast selector - DownloadService downloadService = DownloadService.getInstance(); + final int instance = Util.getActiveServer(context); + final int instanceHash = (instance == 0) ? 0 : Util.getRestUrl(context, null).hashCode(); + if(UserUtil.instance == instance && UserUtil.instanceHash == instanceHash && currentUser != null) { + return; + } else { + UserUtil.instance = instance; + UserUtil.instanceHash = instanceHash; + } - return null; - } + new SilentBackgroundTask(context) { + @Override + protected Void doInBackground() throws Throwable { + currentUser = MusicServiceFactory.getMusicService(context).getUser(refresh, getCurrentUsername(context, instance), context, null); - @Override - protected void done(Void result) { - if(context instanceof AppCompatActivity) { - ((AppCompatActivity) context).supportInvalidateOptionsMenu(); - } - } + // If running, redo cast selector + DownloadService downloadService = DownloadService.getInstance(); - @Override - protected void error(Throwable error) { - // Don't do anything, supposed to be background pull - Log.e(TAG, "Failed to seed user information"); - } - }.execute(); - } + return null; + } - public static User getCurrentUser() { - return currentUser; - } - public static String getCurrentUsername(Context context, int instance) { - SharedPreferences prefs = Util.getPreferences(context); - return prefs.getString(Constants.PREFERENCES_KEY_USERNAME + instance, null); - } + @Override + protected void done(Void result) { + if(context instanceof AppCompatActivity) { + ((AppCompatActivity) context).supportInvalidateOptionsMenu(); + } + } - public static String getCurrentUsername(Context context) { - return getCurrentUsername(context, Util.getActiveServer(context)); - } + @Override + protected void error(Throwable error) { + // Don't do anything, supposed to be background pull + Log.e(TAG, "Failed to seed user information"); + } + }.execute(); + } + + public static User getCurrentUser() { + return currentUser; + } + public static String getCurrentUsername(Context context, int instance) { + SharedPreferences prefs = Util.getPreferences(context); + return prefs.getString(Constants.PREFERENCES_KEY_USERNAME + instance, null); + } + + public static String getCurrentUsername(Context context) { + return getCurrentUsername(context, Util.getActiveServer(context)); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/Util.java b/app/src/main/java/net/nullsum/audinaut/util/Util.java index d7b72a0..61950ae 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/Util.java +++ b/app/src/main/java/net/nullsum/audinaut/util/Util.java @@ -110,36 +110,36 @@ public final class Util { public static final String EVENT_META_CHANGED = "net.nullsum.audinaut.EVENT_META_CHANGED"; public static final String EVENT_PLAYSTATE_CHANGED = "net.nullsum.audinaut.EVENT_PLAYSTATE_CHANGED"; - - public static final String AVRCP_PLAYSTATE_CHANGED = "com.android.music.playstatechanged"; - public static final String AVRCP_METADATA_CHANGED = "com.android.music.metachanged"; - private static OnAudioFocusChangeListener focusListener; - private static boolean pauseFocus = false; - private static boolean lowerFocus = false; + public static final String AVRCP_PLAYSTATE_CHANGED = "com.android.music.playstatechanged"; + public static final String AVRCP_METADATA_CHANGED = "com.android.music.metachanged"; + + private static OnAudioFocusChangeListener focusListener; + private static boolean pauseFocus = false; + private static boolean lowerFocus = false; // Used by hexEncode() private static final char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; private static Toast toast; - // private static Map> tokens = new HashMap<>(); - private static SparseArray> tokens = new SparseArray<>(); - private static Random random; + // private static Map> tokens = new HashMap<>(); + private static SparseArray> tokens = new SparseArray<>(); + private static Random random; private Util() { } public static boolean isOffline(Context context) { SharedPreferences prefs = getPreferences(context); - return prefs.getBoolean(Constants.PREFERENCES_KEY_OFFLINE, false); + return prefs.getBoolean(Constants.PREFERENCES_KEY_OFFLINE, false); + } + + public static void setOffline(Context context, boolean offline) { + SharedPreferences prefs = getPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean(Constants.PREFERENCES_KEY_OFFLINE, offline); + editor.apply(); } - - public static void setOffline(Context context, boolean offline) { - SharedPreferences prefs = getPreferences(context); - SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(Constants.PREFERENCES_KEY_OFFLINE, offline); - editor.apply(); - } public static boolean isScreenLitOnDownload(Context context) { SharedPreferences prefs = getPreferences(context); @@ -167,67 +167,67 @@ public final class Util { public static int getActiveServer(Context context) { SharedPreferences prefs = getPreferences(context); - // Don't allow the SERVER_INSTANCE to ever be 0 + // Don't allow the SERVER_INSTANCE to ever be 0 return prefs.getBoolean(Constants.PREFERENCES_KEY_OFFLINE, false) ? 0 : Math.max(1, prefs.getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1)); } - public static int getMostRecentActiveServer(Context context) { - SharedPreferences prefs = getPreferences(context); - return Math.max(1, prefs.getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1)); - } - - public static int getServerCount(Context context) { - SharedPreferences prefs = getPreferences(context); - return prefs.getInt(Constants.PREFERENCES_KEY_SERVER_COUNT, 1); - } + public static int getMostRecentActiveServer(Context context) { + SharedPreferences prefs = getPreferences(context); + return Math.max(1, prefs.getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1)); + } - public static void removeInstanceName(Context context, int instance, int activeInstance) { - SharedPreferences prefs = getPreferences(context); - SharedPreferences.Editor editor = prefs.edit(); + public static int getServerCount(Context context) { + SharedPreferences prefs = getPreferences(context); + return prefs.getInt(Constants.PREFERENCES_KEY_SERVER_COUNT, 1); + } - int newInstance = instance + 1; + public static void removeInstanceName(Context context, int instance, int activeInstance) { + SharedPreferences prefs = getPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); - // Get what the +1 server details are - String server = prefs.getString(Constants.PREFERENCES_KEY_SERVER_KEY + newInstance, null); - String serverName = prefs.getString(Constants.PREFERENCES_KEY_SERVER_NAME + newInstance, null); - String serverUrl = prefs.getString(Constants.PREFERENCES_KEY_SERVER_URL + newInstance, null); - String userName = prefs.getString(Constants.PREFERENCES_KEY_USERNAME + newInstance, null); - String password = prefs.getString(Constants.PREFERENCES_KEY_PASSWORD + newInstance, null); - String musicFolderId = prefs.getString(Constants.PREFERENCES_KEY_MUSIC_FOLDER_ID + newInstance, null); + int newInstance = instance + 1; - // Store the +1 server details in the to be deleted instance - editor.putString(Constants.PREFERENCES_KEY_SERVER_KEY + instance, server); - editor.putString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, serverName); - editor.putString(Constants.PREFERENCES_KEY_SERVER_URL + instance, serverUrl); - editor.putString(Constants.PREFERENCES_KEY_USERNAME + instance, userName); - editor.putString(Constants.PREFERENCES_KEY_PASSWORD + instance, password); - editor.putString(Constants.PREFERENCES_KEY_MUSIC_FOLDER_ID + instance, musicFolderId); + // Get what the +1 server details are + String server = prefs.getString(Constants.PREFERENCES_KEY_SERVER_KEY + newInstance, null); + String serverName = prefs.getString(Constants.PREFERENCES_KEY_SERVER_NAME + newInstance, null); + String serverUrl = prefs.getString(Constants.PREFERENCES_KEY_SERVER_URL + newInstance, null); + String userName = prefs.getString(Constants.PREFERENCES_KEY_USERNAME + newInstance, null); + String password = prefs.getString(Constants.PREFERENCES_KEY_PASSWORD + newInstance, null); + String musicFolderId = prefs.getString(Constants.PREFERENCES_KEY_MUSIC_FOLDER_ID + newInstance, null); - // Delete the +1 server instance - // Calling method will loop up to fill this in if +2 server exists - editor.putString(Constants.PREFERENCES_KEY_SERVER_KEY + newInstance, null); - editor.putString(Constants.PREFERENCES_KEY_SERVER_NAME + newInstance, null); - editor.putString(Constants.PREFERENCES_KEY_SERVER_URL + newInstance, null); - editor.putString(Constants.PREFERENCES_KEY_USERNAME + newInstance, null); - editor.putString(Constants.PREFERENCES_KEY_PASSWORD + newInstance, null); - editor.putString(Constants.PREFERENCES_KEY_MUSIC_FOLDER_ID + newInstance, null); - editor.apply(); + // Store the +1 server details in the to be deleted instance + editor.putString(Constants.PREFERENCES_KEY_SERVER_KEY + instance, server); + editor.putString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, serverName); + editor.putString(Constants.PREFERENCES_KEY_SERVER_URL + instance, serverUrl); + editor.putString(Constants.PREFERENCES_KEY_USERNAME + instance, userName); + editor.putString(Constants.PREFERENCES_KEY_PASSWORD + instance, password); + editor.putString(Constants.PREFERENCES_KEY_MUSIC_FOLDER_ID + instance, musicFolderId); - if (instance == activeInstance) { - if(instance != 1) { - Util.setActiveServer(context, 1); - } else { - Util.setOffline(context, true); - } - } else if (newInstance == activeInstance) { - Util.setActiveServer(context, instance); - } - } + // Delete the +1 server instance + // Calling method will loop up to fill this in if +2 server exists + editor.putString(Constants.PREFERENCES_KEY_SERVER_KEY + newInstance, null); + editor.putString(Constants.PREFERENCES_KEY_SERVER_NAME + newInstance, null); + editor.putString(Constants.PREFERENCES_KEY_SERVER_URL + newInstance, null); + editor.putString(Constants.PREFERENCES_KEY_USERNAME + newInstance, null); + editor.putString(Constants.PREFERENCES_KEY_PASSWORD + newInstance, null); + editor.putString(Constants.PREFERENCES_KEY_MUSIC_FOLDER_ID + newInstance, null); + editor.apply(); - public static String getServerName(Context context) { - SharedPreferences prefs = getPreferences(context); - int instance = prefs.getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1); + if (instance == activeInstance) { + if(instance != 1) { + Util.setActiveServer(context, 1); + } else { + Util.setOffline(context, true); + } + } else if (newInstance == activeInstance) { + Util.setActiveServer(context, instance); + } + } + + public static String getServerName(Context context) { + SharedPreferences prefs = getPreferences(context); + int instance = prefs.getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1); return prefs.getString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, null); - } + } public static String getServerName(Context context, int instance) { SharedPreferences prefs = getPreferences(context); return prefs.getString(Constants.PREFERENCES_KEY_SERVER_NAME + instance, null); @@ -244,30 +244,30 @@ public final class Util { public static String getSelectedMusicFolderId(Context context) { return getSelectedMusicFolderId(context, getActiveServer(context)); } - public static String getSelectedMusicFolderId(Context context, int instance) { - SharedPreferences prefs = getPreferences(context); - return prefs.getString(Constants.PREFERENCES_KEY_MUSIC_FOLDER_ID + instance, null); - } + public static String getSelectedMusicFolderId(Context context, int instance) { + SharedPreferences prefs = getPreferences(context); + return prefs.getString(Constants.PREFERENCES_KEY_MUSIC_FOLDER_ID + instance, null); + } - public static boolean getAlbumListsPerFolder(Context context) { - return getAlbumListsPerFolder(context, getActiveServer(context)); - } - public static boolean getAlbumListsPerFolder(Context context, int instance) { - SharedPreferences prefs = getPreferences(context); - return prefs.getBoolean(Constants.PREFERENCES_KEY_ALBUMS_PER_FOLDER + instance, false); - } - public static void setAlbumListsPerFolder(Context context, boolean perFolder) { - int instance = getActiveServer(context); - SharedPreferences prefs = getPreferences(context); - SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(Constants.PREFERENCES_KEY_ALBUMS_PER_FOLDER + instance, perFolder); - editor.apply(); - } - - public static boolean getDisplayTrack(Context context) { - SharedPreferences prefs = getPreferences(context); + public static boolean getAlbumListsPerFolder(Context context) { + return getAlbumListsPerFolder(context, getActiveServer(context)); + } + public static boolean getAlbumListsPerFolder(Context context, int instance) { + SharedPreferences prefs = getPreferences(context); + return prefs.getBoolean(Constants.PREFERENCES_KEY_ALBUMS_PER_FOLDER + instance, false); + } + public static void setAlbumListsPerFolder(Context context, boolean perFolder) { + int instance = getActiveServer(context); + SharedPreferences prefs = getPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean(Constants.PREFERENCES_KEY_ALBUMS_PER_FOLDER + instance, perFolder); + editor.apply(); + } + + public static boolean getDisplayTrack(Context context) { + SharedPreferences prefs = getPreferences(context); return prefs.getBoolean(Constants.PREFERENCES_KEY_DISPLAY_TRACK, false); - } + } public static int getMaxBitrate(Context context) { ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); @@ -280,16 +280,16 @@ public final class Util { SharedPreferences prefs = getPreferences(context); return Integer.parseInt(prefs.getString(wifi ? Constants.PREFERENCES_KEY_MAX_BITRATE_WIFI : Constants.PREFERENCES_KEY_MAX_BITRATE_MOBILE, "0")); } - + public static int getPreloadCount(Context context) { - ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = manager.getActiveNetworkInfo(); if (networkInfo == null) { return 3; } - + SharedPreferences prefs = getPreferences(context); - boolean wifi = networkInfo.getType() == ConnectivityManager.TYPE_WIFI; + boolean wifi = networkInfo.getType() == ConnectivityManager.TYPE_WIFI; int preloadCount = Integer.parseInt(prefs.getString(wifi ? Constants.PREFERENCES_KEY_PRELOAD_COUNT_WIFI : Constants.PREFERENCES_KEY_PRELOAD_COUNT_MOBILE, "-1")); return preloadCount == -1 ? Integer.MAX_VALUE : preloadCount; } @@ -299,28 +299,28 @@ public final class Util { int cacheSize = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_CACHE_SIZE, "-1")); return cacheSize == -1 ? Integer.MAX_VALUE : cacheSize; } - public static boolean isBatchMode(Context context) { - return Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_BATCH_MODE, false); - } - public static void setBatchMode(Context context, boolean batchMode) { - Util.getPreferences(context).edit().putBoolean(Constants.PREFERENCES_KEY_BATCH_MODE, batchMode).apply(); - } + public static boolean isBatchMode(Context context) { + return Util.getPreferences(context).getBoolean(Constants.PREFERENCES_KEY_BATCH_MODE, false); + } + public static void setBatchMode(Context context, boolean batchMode) { + Util.getPreferences(context).edit().putBoolean(Constants.PREFERENCES_KEY_BATCH_MODE, batchMode).apply(); + } public static String getRestUrl(Context context, String method) { return getRestUrl(context, method, true); } - public static String getRestUrl(Context context, String method, boolean allowAltAddress) { - SharedPreferences prefs = getPreferences(context); - int instance = prefs.getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1); - return getRestUrl(context, method, prefs, instance, allowAltAddress); - } - public static String getRestUrl(Context context, String method, int instance) { - return getRestUrl(context, method, instance, true); + public static String getRestUrl(Context context, String method, boolean allowAltAddress) { + SharedPreferences prefs = getPreferences(context); + int instance = prefs.getInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1); + return getRestUrl(context, method, prefs, instance, allowAltAddress); + } + public static String getRestUrl(Context context, String method, int instance) { + return getRestUrl(context, method, instance, true); + } + public static String getRestUrl(Context context, String method, int instance, boolean allowAltAddress) { + SharedPreferences prefs = getPreferences(context); + return getRestUrl(context, method, prefs, instance, allowAltAddress); } - public static String getRestUrl(Context context, String method, int instance, boolean allowAltAddress) { - SharedPreferences prefs = getPreferences(context); - return getRestUrl(context, method, prefs, instance, allowAltAddress); - } public static String getRestUrl(Context context, String method, SharedPreferences prefs, int instance) { return getRestUrl(context, method, prefs, instance, true); } @@ -371,189 +371,189 @@ public final class Util { return builder.build().toString(); } - public static int getRestUrlHash(Context context) { - return getRestUrlHash(context, Util.getMostRecentActiveServer(context)); - } - public static int getRestUrlHash(Context context, int instance) { - StringBuilder builder = new StringBuilder(); + public static int getRestUrlHash(Context context) { + return getRestUrlHash(context, Util.getMostRecentActiveServer(context)); + } + public static int getRestUrlHash(Context context, int instance) { + StringBuilder builder = new StringBuilder(); - SharedPreferences prefs = Util.getPreferences(context); - builder.append(prefs.getString(Constants.PREFERENCES_KEY_SERVER_URL + instance, null)); - builder.append(prefs.getString(Constants.PREFERENCES_KEY_USERNAME + instance, null)); + SharedPreferences prefs = Util.getPreferences(context); + builder.append(prefs.getString(Constants.PREFERENCES_KEY_SERVER_URL + instance, null)); + builder.append(prefs.getString(Constants.PREFERENCES_KEY_USERNAME + instance, null)); - return builder.toString().hashCode(); - } + return builder.toString().hashCode(); + } - public static String getBlockTokenUsePref(Context context, int instance) { - return Constants.CACHE_BLOCK_TOKEN_USE + Util.getRestUrl(context, null, instance, false); - } - public static boolean getBlockTokenUse(Context context, int instance) { - return getPreferences(context).getBoolean(getBlockTokenUsePref(context, instance), false); - } - public static void setBlockTokenUse(Context context, int instance, boolean block) { - SharedPreferences.Editor editor = getPreferences(context).edit(); - editor.putBoolean(getBlockTokenUsePref(context, instance), block); - editor.apply(); - } + public static String getBlockTokenUsePref(Context context, int instance) { + return Constants.CACHE_BLOCK_TOKEN_USE + Util.getRestUrl(context, null, instance, false); + } + public static boolean getBlockTokenUse(Context context, int instance) { + return getPreferences(context).getBoolean(getBlockTokenUsePref(context, instance), false); + } + public static void setBlockTokenUse(Context context, int instance, boolean block) { + SharedPreferences.Editor editor = getPreferences(context).edit(); + editor.putBoolean(getBlockTokenUsePref(context, instance), block); + editor.apply(); + } - public static boolean isTagBrowsing(Context context) { - return isTagBrowsing(context, Util.getActiveServer(context)); - } - public static boolean isTagBrowsing(Context context, int instance) { + public static boolean isTagBrowsing(Context context) { + return isTagBrowsing(context, Util.getActiveServer(context)); + } + public static boolean isTagBrowsing(Context context, int instance) { return true; - } - - public static String getParentFromEntry(Context context, MusicDirectory.Entry entry) { - if(Util.isTagBrowsing(context)) { - if(!entry.isDirectory()) { - return entry.getAlbumId(); - } else if(entry.isAlbum()) { - return entry.getArtistId(); - } else { - return null; - } - } else { - return entry.getParent(); - } - } + } - public static String openToTab(Context context) { + public static String getParentFromEntry(Context context, MusicDirectory.Entry entry) { + if(Util.isTagBrowsing(context)) { + if(!entry.isDirectory()) { + return entry.getAlbumId(); + } else if(entry.isAlbum()) { + return entry.getArtistId(); + } else { + return null; + } + } else { + return entry.getParent(); + } + } + + public static String openToTab(Context context) { return "Library"; - } + } public static SharedPreferences getPreferences(Context context) { return context.getSharedPreferences(Constants.PREFERENCES_FILE_NAME, 0); } - public static SharedPreferences getOfflineSync(Context context) { - return context.getSharedPreferences(Constants.OFFLINE_SYNC_NAME, 0); - } - - public static String getSyncDefault(Context context) { - SharedPreferences prefs = Util.getOfflineSync(context); - return prefs.getString(Constants.OFFLINE_SYNC_DEFAULT, null); - } - public static void setSyncDefault(Context context, String defaultValue) { - SharedPreferences.Editor editor = Util.getOfflineSync(context).edit(); - editor.putString(Constants.OFFLINE_SYNC_DEFAULT, defaultValue); - editor.apply(); - } + public static SharedPreferences getOfflineSync(Context context) { + return context.getSharedPreferences(Constants.OFFLINE_SYNC_NAME, 0); + } - public static String getCacheName(Context context, String name, String id) { - return getCacheName(context, getActiveServer(context), name, id); - } - public static String getCacheName(Context context, int instance, String name, String id) { - String s = getRestUrl(context, null, instance, false) + id; - return name + "-" + s.hashCode() + ".ser"; - } - public static String getCacheName(Context context, String name) { - return getCacheName(context, getActiveServer(context), name); - } - public static String getCacheName(Context context, int instance, String name) { - String s = getRestUrl(context, null, instance, false); - return name + "-" + s.hashCode() + ".ser"; - } - - public static int offlineStarsCount(Context context) { - SharedPreferences offline = getOfflineSync(context); - return offline.getInt(Constants.OFFLINE_STAR_COUNT, 0); - } - - public static String parseOfflineIDSearch(Context context, String id, String cacheLocation) { - // Try to get this info based off of tags first - String name = parseOfflineIDSearch(id); - if(name != null) { - return name; - } + public static String getSyncDefault(Context context) { + SharedPreferences prefs = Util.getOfflineSync(context); + return prefs.getString(Constants.OFFLINE_SYNC_DEFAULT, null); + } + public static void setSyncDefault(Context context, String defaultValue) { + SharedPreferences.Editor editor = Util.getOfflineSync(context).edit(); + editor.putString(Constants.OFFLINE_SYNC_DEFAULT, defaultValue); + editor.apply(); + } - // Otherwise go nuts trying to parse from file structure - name = id.replace(cacheLocation, ""); - if(name.startsWith("/")) { - name = name.substring(1); - } - name = name.replace(".complete", "").replace(".partial", ""); - int index = name.lastIndexOf("."); - name = index == -1 ? name : name.substring(0, index); - String[] details = name.split("/"); - - String title = details[details.length - 1]; - if(index == -1) { - if(details.length > 1) { - String artist = "artist:\"" + details[details.length - 2] + "\""; - String simpleArtist = "artist:\"" + title + "\""; - title = "album:\"" + title + "\""; - if(details[details.length - 1].equals(details[details.length - 2])) { - name = title; - } else { - name = "(" + artist + " AND " + title + ")" + " OR " + simpleArtist; - } - } else { - name = "artist:\"" + title + "\" OR album:\"" + title + "\""; - } - } else { - String artist; - if(details.length > 2) { - artist = "artist:\"" + details[details.length - 3] + "\""; - } else { - artist = "(artist:\"" + details[0] + "\" OR album:\"" + details[0] + "\")"; - } - title = "title:\"" + title.substring(title.indexOf('-') + 1) + "\""; - name = artist + " AND " + title; - } - - return name; - } + public static String getCacheName(Context context, String name, String id) { + return getCacheName(context, getActiveServer(context), name, id); + } + public static String getCacheName(Context context, int instance, String name, String id) { + String s = getRestUrl(context, null, instance, false) + id; + return name + "-" + s.hashCode() + ".ser"; + } + public static String getCacheName(Context context, String name) { + return getCacheName(context, getActiveServer(context), name); + } + public static String getCacheName(Context context, int instance, String name) { + String s = getRestUrl(context, null, instance, false); + return name + "-" + s.hashCode() + ".ser"; + } - public static String parseOfflineIDSearch(String id) { - MusicDirectory.Entry entry = new MusicDirectory.Entry(); - File file = new File(id); + public static int offlineStarsCount(Context context) { + SharedPreferences offline = getOfflineSync(context); + return offline.getInt(Constants.OFFLINE_STAR_COUNT, 0); + } - if(file.exists()) { - entry.loadMetadata(file); + public static String parseOfflineIDSearch(Context context, String id, String cacheLocation) { + // Try to get this info based off of tags first + String name = parseOfflineIDSearch(id); + if(name != null) { + return name; + } - if(entry.getArtist() != null) { - String title = file.getName(); - title = title.replace(".complete", "").replace(".partial", ""); - int index = title.lastIndexOf("."); - title = index == -1 ? title : title.substring(0, index); - title = title.substring(title.indexOf('-') + 1); + // Otherwise go nuts trying to parse from file structure + name = id.replace(cacheLocation, ""); + if(name.startsWith("/")) { + name = name.substring(1); + } + name = name.replace(".complete", "").replace(".partial", ""); + int index = name.lastIndexOf("."); + name = index == -1 ? name : name.substring(0, index); + String[] details = name.split("/"); - String query = "artist:\"" + entry.getArtist() + "\"" + - " AND title:\"" + title + "\""; + String title = details[details.length - 1]; + if(index == -1) { + if(details.length > 1) { + String artist = "artist:\"" + details[details.length - 2] + "\""; + String simpleArtist = "artist:\"" + title + "\""; + title = "album:\"" + title + "\""; + if(details[details.length - 1].equals(details[details.length - 2])) { + name = title; + } else { + name = "(" + artist + " AND " + title + ")" + " OR " + simpleArtist; + } + } else { + name = "artist:\"" + title + "\" OR album:\"" + title + "\""; + } + } else { + String artist; + if(details.length > 2) { + artist = "artist:\"" + details[details.length - 3] + "\""; + } else { + artist = "(artist:\"" + details[0] + "\" OR album:\"" + details[0] + "\")"; + } + title = "title:\"" + title.substring(title.indexOf('-') + 1) + "\""; + name = artist + " AND " + title; + } - return query; - } else { - return null; - } - } else { - return null; - } - } + return name; + } - public static boolean isFirstLevelArtist(Context context) { - SharedPreferences prefs = getPreferences(context); - return prefs.getBoolean(Constants.PREFERENCES_KEY_FIRST_LEVEL_ARTIST + getActiveServer(context), true); - } - public static void toggleFirstLevelArtist(Context context) { - SharedPreferences prefs = Util.getPreferences(context); - SharedPreferences.Editor editor = prefs.edit(); + public static String parseOfflineIDSearch(String id) { + MusicDirectory.Entry entry = new MusicDirectory.Entry(); + File file = new File(id); - if(prefs.getBoolean(Constants.PREFERENCES_KEY_FIRST_LEVEL_ARTIST + getActiveServer(context), true)) { - editor.putBoolean(Constants.PREFERENCES_KEY_FIRST_LEVEL_ARTIST + getActiveServer(context), false); - } else { - editor.putBoolean(Constants.PREFERENCES_KEY_FIRST_LEVEL_ARTIST + getActiveServer(context), true); - } + if(file.exists()) { + entry.loadMetadata(file); - editor.apply(); - } + if(entry.getArtist() != null) { + String title = file.getName(); + title = title.replace(".complete", "").replace(".partial", ""); + int index = title.lastIndexOf("."); + title = index == -1 ? title : title.substring(0, index); + title = title.substring(title.indexOf('-') + 1); - public static boolean shouldStartOnHeadphones(Context context) { - SharedPreferences prefs = getPreferences(context); - return prefs.getBoolean(Constants.PREFERENCES_KEY_START_ON_HEADPHONES, false); - } + String query = "artist:\"" + entry.getArtist() + "\"" + + " AND title:\"" + title + "\""; - public static String getSongPressAction(Context context) { - return getPreferences(context).getString(Constants.PREFERENCES_KEY_SONG_PRESS_ACTION, "all"); - } + return query; + } else { + return null; + } + } else { + return null; + } + } + + public static boolean isFirstLevelArtist(Context context) { + SharedPreferences prefs = getPreferences(context); + return prefs.getBoolean(Constants.PREFERENCES_KEY_FIRST_LEVEL_ARTIST + getActiveServer(context), true); + } + public static void toggleFirstLevelArtist(Context context) { + SharedPreferences prefs = Util.getPreferences(context); + SharedPreferences.Editor editor = prefs.edit(); + + if(prefs.getBoolean(Constants.PREFERENCES_KEY_FIRST_LEVEL_ARTIST + getActiveServer(context), true)) { + editor.putBoolean(Constants.PREFERENCES_KEY_FIRST_LEVEL_ARTIST + getActiveServer(context), false); + } else { + editor.putBoolean(Constants.PREFERENCES_KEY_FIRST_LEVEL_ARTIST + getActiveServer(context), true); + } + + editor.apply(); + } + + public static boolean shouldStartOnHeadphones(Context context) { + SharedPreferences prefs = getPreferences(context); + return prefs.getBoolean(Constants.PREFERENCES_KEY_START_ON_HEADPHONES, false); + } + + public static String getSongPressAction(Context context) { + return getPreferences(context).getString(Constants.PREFERENCES_KEY_SONG_PRESS_ACTION, "all"); + } /** * Get the contents of an InputStream as a byte[]. @@ -584,11 +584,11 @@ public final class Util { return count; } - public static void renameFile(File from, File to) throws IOException { - if(!from.renameTo(to)) { - Log.i(TAG, "Failed to rename " + from + " to " + to); - } - } + public static void renameFile(File from, File to) throws IOException { + if(!from.renameTo(to)) { + Log.i(TAG, "Failed to rename " + from + " to " + to); + } + } public static void close(Closeable closeable) { try { @@ -611,7 +611,7 @@ public final class Util { return true; } - public static void toast(Context context, int messageId) { + public static void toast(Context context, int messageId) { toast(context, messageId, true); } @@ -633,28 +633,28 @@ public final class Util { } toast.show(); } - - public static void confirmDialog(Context context, int action, int subject, DialogInterface.OnClickListener onClick) { - Util.confirmDialog(context, context.getResources().getString(action).toLowerCase(), context.getResources().getString(subject), onClick, null); - } - public static void confirmDialog(Context context, int action, int subject, DialogInterface.OnClickListener onClick, DialogInterface.OnClickListener onCancel) { - Util.confirmDialog(context, context.getResources().getString(action).toLowerCase(), context.getResources().getString(subject), onClick, onCancel); - } - public static void confirmDialog(Context context, int action, String subject, DialogInterface.OnClickListener onClick) { - Util.confirmDialog(context, context.getResources().getString(action).toLowerCase(), subject, onClick, null); - } - public static void confirmDialog(Context context, int action, String subject, DialogInterface.OnClickListener onClick, DialogInterface.OnClickListener onCancel) { - Util.confirmDialog(context, context.getResources().getString(action).toLowerCase(), subject, onClick, onCancel); - } - public static void confirmDialog(Context context, String action, String subject, DialogInterface.OnClickListener onClick, DialogInterface.OnClickListener onCancel) { - new AlertDialog.Builder(context) - .setIcon(android.R.drawable.ic_dialog_alert) - .setTitle(R.string.common_confirm) - .setMessage(context.getResources().getString(R.string.common_confirm_message, action, subject)) - .setPositiveButton(R.string.common_ok, onClick) - .setNegativeButton(R.string.common_cancel, onCancel) - .show(); - } + + public static void confirmDialog(Context context, int action, int subject, DialogInterface.OnClickListener onClick) { + Util.confirmDialog(context, context.getResources().getString(action).toLowerCase(), context.getResources().getString(subject), onClick, null); + } + public static void confirmDialog(Context context, int action, int subject, DialogInterface.OnClickListener onClick, DialogInterface.OnClickListener onCancel) { + Util.confirmDialog(context, context.getResources().getString(action).toLowerCase(), context.getResources().getString(subject), onClick, onCancel); + } + public static void confirmDialog(Context context, int action, String subject, DialogInterface.OnClickListener onClick) { + Util.confirmDialog(context, context.getResources().getString(action).toLowerCase(), subject, onClick, null); + } + public static void confirmDialog(Context context, int action, String subject, DialogInterface.OnClickListener onClick, DialogInterface.OnClickListener onCancel) { + Util.confirmDialog(context, context.getResources().getString(action).toLowerCase(), subject, onClick, onCancel); + } + public static void confirmDialog(Context context, String action, String subject, DialogInterface.OnClickListener onClick, DialogInterface.OnClickListener onCancel) { + new AlertDialog.Builder(context) + .setIcon(android.R.drawable.ic_dialog_alert) + .setTitle(R.string.common_confirm) + .setMessage(context.getResources().getString(R.string.common_confirm_message, action, subject)) + .setPositiveButton(R.string.common_ok, onClick) + .setNegativeButton(R.string.common_cancel, onCancel) + .show(); + } /** * Converts a byte-count to a formatted string suitable for display to the user. @@ -748,17 +748,17 @@ public final class Util { return null; } - int hours = seconds / 3600; + int hours = seconds / 3600; int minutes = (seconds / 60) % 60; int secs = seconds % 60; StringBuilder builder = new StringBuilder(7); - if(hours > 0) { - builder.append(hours).append(":"); - if(minutes < 10) { - builder.append("0"); - } - } + if(hours > 0) { + builder.append(hours).append(":"); + if(minutes < 10) { + builder.append("0"); + } + } builder.append(minutes).append(":"); if (secs < 10) { builder.append("0"); @@ -767,9 +767,9 @@ public final class Util { return builder.toString(); } - public static String formatBoolean(Context context, boolean value) { - return context.getResources().getString(value ? R.string.common_true : R.string.common_false); - } + public static String formatBoolean(Context context, boolean value) { + return context.getResources().getString(value ? R.string.common_true : R.string.common_false); + } public static boolean equals(Object object1, Object object2) { if (object1 == object2) { @@ -819,253 +819,253 @@ public final class Util { throw new RuntimeException(x.getMessage(), x); } } - - public static boolean isNullOrWhiteSpace(String string) { - return string == null || "".equals(string) || "".equals(string.trim()); - } - public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { - // Raw height and width of image - final int height = options.outHeight; - final int width = options.outWidth; - int inSampleSize = 1; + public static boolean isNullOrWhiteSpace(String string) { + return string == null || "".equals(string) || "".equals(string.trim()); + } - if (height > reqHeight || width > reqWidth) { + public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { + // Raw height and width of image + final int height = options.outHeight; + final int width = options.outWidth; + int inSampleSize = 1; - // Calculate ratios of height and width to requested height and - // width - final int heightRatio = Math.round((float) height / (float) reqHeight); - final int widthRatio = Math.round((float) width / (float) reqWidth); + if (height > reqHeight || width > reqWidth) { - // Choose the smallest ratio as inSampleSize value, this will - // guarantee - // a final image with both dimensions larger than or equal to the - // requested height and width. - inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; - } + // Calculate ratios of height and width to requested height and + // width + final int heightRatio = Math.round((float) height / (float) reqHeight); + final int widthRatio = Math.round((float) width / (float) reqWidth); - return inSampleSize; - } + // Choose the smallest ratio as inSampleSize value, this will + // guarantee + // a final image with both dimensions larger than or equal to the + // requested height and width. + inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; + } - public static int getScaledHeight(double height, double width, int newWidth) { - // Try to keep correct aspect ratio of the original image, do not force a square - double aspectRatio = height / width; + return inSampleSize; + } - // Assume the size given refers to the width of the image, so calculate the new height using - // the previously determined aspect ratio - return (int) Math.round(newWidth * aspectRatio); - } + public static int getScaledHeight(double height, double width, int newWidth) { + // Try to keep correct aspect ratio of the original image, do not force a square + double aspectRatio = height / width; - public static int getScaledHeight(Bitmap bitmap, int width) { - return Util.getScaledHeight((double) bitmap.getHeight(), (double) bitmap.getWidth(), width); - } + // Assume the size given refers to the width of the image, so calculate the new height using + // the previously determined aspect ratio + return (int) Math.round(newWidth * aspectRatio); + } - public static int getStringDistance(CharSequence s, CharSequence t) { - if (s == null || t == null) { - throw new IllegalArgumentException("Strings must not be null"); - } + public static int getScaledHeight(Bitmap bitmap, int width) { + return Util.getScaledHeight((double) bitmap.getHeight(), (double) bitmap.getWidth(), width); + } - if(t.toString().toLowerCase().indexOf(s.toString().toLowerCase()) != -1) { - return 1; - } + public static int getStringDistance(CharSequence s, CharSequence t) { + if (s == null || t == null) { + throw new IllegalArgumentException("Strings must not be null"); + } + + if(t.toString().toLowerCase().indexOf(s.toString().toLowerCase()) != -1) { + return 1; + } int n = s.length(); - int m = t.length(); + int m = t.length(); - if (n == 0) { - return m; - } else if (m == 0) { - return n; - } + if (n == 0) { + return m; + } else if (m == 0) { + return n; + } - if (n > m) { - final CharSequence tmp = s; - s = t; - t = tmp; - n = m; - m = t.length(); - } + if (n > m) { + final CharSequence tmp = s; + s = t; + t = tmp; + n = m; + m = t.length(); + } - int p[] = new int[n + 1]; - int d[] = new int[n + 1]; - int _d[]; + int p[] = new int[n + 1]; + int d[] = new int[n + 1]; + int _d[]; - int i; - int j; - char t_j; - int cost; + int i; + int j; + char t_j; + int cost; - for (i = 0; i <= n; i++) { - p[i] = i; - } + for (i = 0; i <= n; i++) { + p[i] = i; + } - for (j = 1; j <= m; j++) { - t_j = t.charAt(j - 1); - d[0] = j; + for (j = 1; j <= m; j++) { + t_j = t.charAt(j - 1); + d[0] = j; - for (i = 1; i <= n; i++) { - cost = s.charAt(i - 1) == t_j ? 0 : 1; - d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost); - } + for (i = 1; i <= n; i++) { + cost = s.charAt(i - 1) == t_j ? 0 : 1; + d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost); + } - _d = p; - p = d; - d = _d; - } + _d = p; + p = d; + d = _d; + } - return p[n]; - } + return p[n]; + } - public static boolean isNetworkConnected(Context context) { - return isNetworkConnected(context, false); - } + public static boolean isNetworkConnected(Context context) { + return isNetworkConnected(context, false); + } public static boolean isNetworkConnected(Context context, boolean streaming) { ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = manager.getActiveNetworkInfo(); boolean connected = networkInfo != null && networkInfo.isConnected(); - if(streaming) { - boolean wifiConnected = connected && networkInfo.getType() == ConnectivityManager.TYPE_WIFI; - boolean wifiRequired = isWifiRequiredForDownload(context); + if(streaming) { + boolean wifiConnected = connected && networkInfo.getType() == ConnectivityManager.TYPE_WIFI; + boolean wifiRequired = isWifiRequiredForDownload(context); - return connected && (!wifiRequired || wifiConnected); - } else { - return connected; - } + return connected && (!wifiRequired || wifiConnected); + } else { + return connected; + } + } + public static boolean isWifiConnected(Context context) { + ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo networkInfo = manager.getActiveNetworkInfo(); + boolean connected = networkInfo != null && networkInfo.isConnected(); + return connected && (networkInfo.getType() == ConnectivityManager.TYPE_WIFI); + } + public static String getSSID(Context context) { + if (isWifiConnected(context)) { + WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); + if (wifiManager.getConnectionInfo() != null && wifiManager.getConnectionInfo().getSSID() != null) { + return wifiManager.getConnectionInfo().getSSID().replace("\"", ""); + } + return null; + } + return null; } - public static boolean isWifiConnected(Context context) { - ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo networkInfo = manager.getActiveNetworkInfo(); - boolean connected = networkInfo != null && networkInfo.isConnected(); - return connected && (networkInfo.getType() == ConnectivityManager.TYPE_WIFI); - } - public static String getSSID(Context context) { - if (isWifiConnected(context)) { - WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); - if (wifiManager.getConnectionInfo() != null && wifiManager.getConnectionInfo().getSSID() != null) { - return wifiManager.getConnectionInfo().getSSID().replace("\"", ""); - } - return null; - } - return null; - } public static boolean isExternalStoragePresent() { return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); } - public static boolean isAllowedToDownload(Context context) { - return isNetworkConnected(context, true) && !isOffline(context); - } + public static boolean isAllowedToDownload(Context context) { + return isNetworkConnected(context, true) && !isOffline(context); + } public static boolean isWifiRequiredForDownload(Context context) { SharedPreferences prefs = getPreferences(context); return prefs.getBoolean(Constants.PREFERENCES_KEY_WIFI_REQUIRED_FOR_DOWNLOAD, false); } public static void info(Context context, int titleId, int messageId) { - info(context, titleId, messageId, true); + info(context, titleId, messageId, true); } - public static void info(Context context, int titleId, String message) { - info(context, titleId, message, true); - } - public static void info(Context context, String title, String message) { - info(context, title, message, true); - } - public static void info(Context context, int titleId, int messageId, boolean linkify) { + public static void info(Context context, int titleId, String message) { + info(context, titleId, message, true); + } + public static void info(Context context, String title, String message) { + info(context, title, message, true); + } + public static void info(Context context, int titleId, int messageId, boolean linkify) { showDialog(context, android.R.drawable.ic_dialog_info, titleId, messageId, linkify); } - public static void info(Context context, int titleId, String message, boolean linkify) { - showDialog(context, android.R.drawable.ic_dialog_info, titleId, message, linkify); - } - public static void info(Context context, String title, String message, boolean linkify) { - showDialog(context, android.R.drawable.ic_dialog_info, title, message, linkify); - } - - public static void showDialog(Context context, int icon, int titleId, int messageId) { - showDialog(context, icon, titleId, messageId, true); - } - public static void showDialog(Context context, int icon, int titleId, String message) { - showDialog(context, icon, titleId, message, true); - } - public static void showDialog(Context context, int icon, String title, String message) { - showDialog(context, icon, title, message, true); - } - public static void showDialog(Context context, int icon, int titleId, int messageId, boolean linkify) { - showDialog(context, icon, context.getResources().getString(titleId), context.getResources().getString(messageId), linkify); - } - public static void showDialog(Context context, int icon, int titleId, String message, boolean linkify) { - showDialog(context, icon, context.getResources().getString(titleId), message, linkify); - } - public static void showDialog(Context context, int icon, String title, String message, boolean linkify) { - SpannableString ss = new SpannableString(message); - if(linkify) { - Linkify.addLinks(ss, Linkify.ALL); - } - - AlertDialog dialog = new AlertDialog.Builder(context) - .setIcon(icon) - .setTitle(title) - .setMessage(ss) - .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int i) { - dialog.dismiss(); - } - }) - .show(); - - ((TextView)dialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance()); + public static void info(Context context, int titleId, String message, boolean linkify) { + showDialog(context, android.R.drawable.ic_dialog_info, titleId, message, linkify); + } + public static void info(Context context, String title, String message, boolean linkify) { + showDialog(context, android.R.drawable.ic_dialog_info, title, message, linkify); } - public static void showDetailsDialog(Context context, @StringRes int title, List headers, List details) { - List headerStrings = new ArrayList<>(); - for(@StringRes Integer res: headers) { - headerStrings.add(context.getResources().getString(res)); - } - showDetailsDialog(context, context.getResources().getString(title), headerStrings, details); - } - public static void showDetailsDialog(Context context, String title, List headers, final List details) { - ListView listView = new ListView(context); - listView.setAdapter(new DetailsAdapter(context, R.layout.details_item, headers, details)); - listView.setDivider(null); - listView.setScrollbarFadingEnabled(false); + public static void showDialog(Context context, int icon, int titleId, int messageId) { + showDialog(context, icon, titleId, messageId, true); + } + public static void showDialog(Context context, int icon, int titleId, String message) { + showDialog(context, icon, titleId, message, true); + } + public static void showDialog(Context context, int icon, String title, String message) { + showDialog(context, icon, title, message, true); + } + public static void showDialog(Context context, int icon, int titleId, int messageId, boolean linkify) { + showDialog(context, icon, context.getResources().getString(titleId), context.getResources().getString(messageId), linkify); + } + public static void showDialog(Context context, int icon, int titleId, String message, boolean linkify) { + showDialog(context, icon, context.getResources().getString(titleId), message, linkify); + } + public static void showDialog(Context context, int icon, String title, String message, boolean linkify) { + SpannableString ss = new SpannableString(message); + if(linkify) { + Linkify.addLinks(ss, Linkify.ALL); + } - // Let the user long-click on a row to copy its value to the clipboard - final Context contextRef = context; - listView.setOnItemLongClickListener(new ListView.OnItemLongClickListener() { - @Override - public boolean onItemLongClick(AdapterView parent, View view, int pos, long id) { - TextView nameView = (TextView) view.findViewById(R.id.detail_name); - TextView detailsView = (TextView) view.findViewById(R.id.detail_value); - if(nameView == null || detailsView == null) { - return false; - } + AlertDialog dialog = new AlertDialog.Builder(context) + .setIcon(icon) + .setTitle(title) + .setMessage(ss) + .setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int i) { + dialog.dismiss(); + } + }) + .show(); - CharSequence name = nameView.getText(); - CharSequence value = detailsView.getText(); + ((TextView)dialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance()); + } - ClipboardManager clipboard = (ClipboardManager) contextRef.getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText(name, value); - clipboard.setPrimaryClip(clip); + public static void showDetailsDialog(Context context, @StringRes int title, List headers, List details) { + List headerStrings = new ArrayList<>(); + for(@StringRes Integer res: headers) { + headerStrings.add(context.getResources().getString(res)); + } + showDetailsDialog(context, context.getResources().getString(title), headerStrings, details); + } + public static void showDetailsDialog(Context context, String title, List headers, final List details) { + ListView listView = new ListView(context); + listView.setAdapter(new DetailsAdapter(context, R.layout.details_item, headers, details)); + listView.setDivider(null); + listView.setScrollbarFadingEnabled(false); - toast(contextRef, "Copied " + name + " to clipboard"); + // Let the user long-click on a row to copy its value to the clipboard + final Context contextRef = context; + listView.setOnItemLongClickListener(new ListView.OnItemLongClickListener() { + @Override + public boolean onItemLongClick(AdapterView parent, View view, int pos, long id) { + TextView nameView = (TextView) view.findViewById(R.id.detail_name); + TextView detailsView = (TextView) view.findViewById(R.id.detail_value); + if(nameView == null || detailsView == null) { + return false; + } - return true; - } - }); + CharSequence name = nameView.getText(); + CharSequence value = detailsView.getText(); - new AlertDialog.Builder(context) - // .setIcon(android.R.drawable.ic_dialog_info) - .setTitle(title) - .setView(listView) - .setPositiveButton(R.string.common_close, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int i) { - dialog.dismiss(); - } - }) - .show(); - } + ClipboardManager clipboard = (ClipboardManager) contextRef.getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText(name, value); + clipboard.setPrimaryClip(clip); + + toast(contextRef, "Copied " + name + " to clipboard"); + + return true; + } + }); + + new AlertDialog.Builder(context) + // .setIcon(android.R.drawable.ic_dialog_info) + .setTitle(title) + .setView(listView) + .setPositiveButton(R.string.common_close, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int i) { + dialog.dismiss(); + } + }) + .show(); + } public static void sleepQuietly(long millis) { try { @@ -1140,170 +1140,170 @@ public final class Util { // Ignored. } } - - public static void requestAudioFocus(final Context context) { - if (focusListener == null) { - final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); - audioManager.requestAudioFocus(focusListener = new OnAudioFocusChangeListener() { - public void onAudioFocusChange(int focusChange) { - DownloadService downloadService = (DownloadService)context; - if((focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)) { - if(downloadService.getPlayerState() == PlayerState.STARTED) { - Log.i(TAG, "Temporary loss of focus"); - SharedPreferences prefs = getPreferences(context); - int lossPref = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_TEMP_LOSS, "1")); - if(lossPref == 2 || (lossPref == 1 && focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)) { - lowerFocus = true; - downloadService.setVolume(0.1f); - } else if(lossPref == 0 || (lossPref == 1 && focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT)) { - pauseFocus = true; - downloadService.pause(true); - } - } - } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { - if(pauseFocus) { - pauseFocus = false; - downloadService.start(); - } - if(lowerFocus) { - lowerFocus = false; - downloadService.setVolume(1.0f); - } - } else if(focusChange == AudioManager.AUDIOFOCUS_LOSS) { - Log.i(TAG, "Permanently lost focus"); - focusListener = null; - downloadService.pause(); - audioManager.abandonAudioFocus(this); - } - } - }, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); - } + + public static void requestAudioFocus(final Context context) { + if (focusListener == null) { + final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + audioManager.requestAudioFocus(focusListener = new OnAudioFocusChangeListener() { + public void onAudioFocusChange(int focusChange) { + DownloadService downloadService = (DownloadService)context; + if((focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT || focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)) { + if(downloadService.getPlayerState() == PlayerState.STARTED) { + Log.i(TAG, "Temporary loss of focus"); + SharedPreferences prefs = getPreferences(context); + int lossPref = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_TEMP_LOSS, "1")); + if(lossPref == 2 || (lossPref == 1 && focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK)) { + lowerFocus = true; + downloadService.setVolume(0.1f); + } else if(lossPref == 0 || (lossPref == 1 && focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT)) { + pauseFocus = true; + downloadService.pause(true); + } + } + } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN) { + if(pauseFocus) { + pauseFocus = false; + downloadService.start(); + } + if(lowerFocus) { + lowerFocus = false; + downloadService.setVolume(1.0f); + } + } else if(focusChange == AudioManager.AUDIOFOCUS_LOSS) { + Log.i(TAG, "Permanently lost focus"); + focusListener = null; + downloadService.pause(); + audioManager.abandonAudioFocus(this); + } + } + }, AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN); + } } - public static void abandonAudioFocus(Context context) { - if(focusListener != null) { - final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); - audioManager.abandonAudioFocus(focusListener); - focusListener = null; - } - } + public static void abandonAudioFocus(Context context) { + if(focusListener != null) { + final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + audioManager.abandonAudioFocus(focusListener); + focusListener = null; + } + } /** *

Broadcasts the given song info as the new song being played.

*/ public static void broadcastNewTrackInfo(Context context, MusicDirectory.Entry song) { - try { - Intent intent = new Intent(EVENT_META_CHANGED); - Intent avrcpIntent = new Intent(AVRCP_METADATA_CHANGED); + try { + Intent intent = new Intent(EVENT_META_CHANGED); + Intent avrcpIntent = new Intent(AVRCP_METADATA_CHANGED); - if (song != null) { - intent.putExtra("title", song.getTitle()); - intent.putExtra("artist", song.getArtist()); - intent.putExtra("album", song.getAlbum()); + if (song != null) { + intent.putExtra("title", song.getTitle()); + intent.putExtra("artist", song.getArtist()); + intent.putExtra("album", song.getAlbum()); - File albumArtFile = FileUtil.getAlbumArtFile(context, song); - intent.putExtra("coverart", albumArtFile.getAbsolutePath()); - avrcpIntent.putExtra("playing", true); - } else { - intent.putExtra("title", ""); - intent.putExtra("artist", ""); - intent.putExtra("album", ""); - intent.putExtra("coverart", ""); - avrcpIntent.putExtra("playing", false); - } - addTrackInfo(context, song, avrcpIntent); + File albumArtFile = FileUtil.getAlbumArtFile(context, song); + intent.putExtra("coverart", albumArtFile.getAbsolutePath()); + avrcpIntent.putExtra("playing", true); + } else { + intent.putExtra("title", ""); + intent.putExtra("artist", ""); + intent.putExtra("album", ""); + intent.putExtra("coverart", ""); + avrcpIntent.putExtra("playing", false); + } + addTrackInfo(context, song, avrcpIntent); - context.sendBroadcast(intent); - context.sendBroadcast(avrcpIntent); - } catch(Exception e) { - Log.e(TAG, "Failed to broadcastNewTrackInfo", e); - } + context.sendBroadcast(intent); + context.sendBroadcast(avrcpIntent); + } catch(Exception e) { + Log.e(TAG, "Failed to broadcastNewTrackInfo", e); + } } /** *

Broadcasts the given player state as the one being set.

*/ public static void broadcastPlaybackStatusChange(Context context, MusicDirectory.Entry song, PlayerState state) { - try { - Intent intent = new Intent(EVENT_PLAYSTATE_CHANGED); - Intent avrcpIntent = new Intent(AVRCP_PLAYSTATE_CHANGED); + try { + Intent intent = new Intent(EVENT_PLAYSTATE_CHANGED); + Intent avrcpIntent = new Intent(AVRCP_PLAYSTATE_CHANGED); - switch (state) { - case STARTED: - intent.putExtra("state", "play"); - avrcpIntent.putExtra("playing", true); - break; - case STOPPED: - intent.putExtra("state", "stop"); - avrcpIntent.putExtra("playing", false); - break; - case PAUSED: - intent.putExtra("state", "pause"); - avrcpIntent.putExtra("playing", false); - break; - case PREPARED: - // Only send quick pause event for samsung devices, causes issues for others - if (Build.MANUFACTURER.toLowerCase().indexOf("samsung") != -1) { - avrcpIntent.putExtra("playing", false); - } else { - return; // Don't broadcast anything - } - break; - case COMPLETED: - intent.putExtra("state", "complete"); - avrcpIntent.putExtra("playing", false); - break; - default: - return; // No need to broadcast. - } - addTrackInfo(context, song, avrcpIntent); + switch (state) { + case STARTED: + intent.putExtra("state", "play"); + avrcpIntent.putExtra("playing", true); + break; + case STOPPED: + intent.putExtra("state", "stop"); + avrcpIntent.putExtra("playing", false); + break; + case PAUSED: + intent.putExtra("state", "pause"); + avrcpIntent.putExtra("playing", false); + break; + case PREPARED: + // Only send quick pause event for samsung devices, causes issues for others + if (Build.MANUFACTURER.toLowerCase().indexOf("samsung") != -1) { + avrcpIntent.putExtra("playing", false); + } else { + return; // Don't broadcast anything + } + break; + case COMPLETED: + intent.putExtra("state", "complete"); + avrcpIntent.putExtra("playing", false); + break; + default: + return; // No need to broadcast. + } + addTrackInfo(context, song, avrcpIntent); - if (state != PlayerState.PREPARED) { - context.sendBroadcast(intent); - } - context.sendBroadcast(avrcpIntent); - } catch(Exception e) { - Log.e(TAG, "Failed to broadcastPlaybackStatusChange", e); - } + if (state != PlayerState.PREPARED) { + context.sendBroadcast(intent); + } + context.sendBroadcast(avrcpIntent); + } catch(Exception e) { + Log.e(TAG, "Failed to broadcastPlaybackStatusChange", e); + } } - private static void addTrackInfo(Context context, MusicDirectory.Entry song, Intent intent) { - if (song != null) { - DownloadService downloadService = (DownloadService)context; - File albumArtFile = FileUtil.getAlbumArtFile(context, song); + private static void addTrackInfo(Context context, MusicDirectory.Entry song, Intent intent) { + if (song != null) { + DownloadService downloadService = (DownloadService)context; + File albumArtFile = FileUtil.getAlbumArtFile(context, song); - intent.putExtra("track", song.getTitle()); - intent.putExtra("artist", song.getArtist()); - intent.putExtra("album", song.getAlbum()); - intent.putExtra("ListSize", (long) downloadService.getSongs().size()); - intent.putExtra("id", (long) downloadService.getCurrentPlayingIndex() + 1); - intent.putExtra("duration", (long) downloadService.getPlayerDuration()); - intent.putExtra("position", (long) downloadService.getPlayerPosition()); - intent.putExtra("coverart", albumArtFile.getAbsolutePath()); - intent.putExtra("package","net.nullsum.audinaut"); - } else { - intent.putExtra("track", ""); - intent.putExtra("artist", ""); - intent.putExtra("album", ""); - intent.putExtra("ListSize", (long) 0); - intent.putExtra("id", (long) 0); - intent.putExtra("duration", (long) 0); - intent.putExtra("position", (long) 0); - intent.putExtra("coverart", ""); - intent.putExtra("package","net.nullsum.audinaut"); - } - } - - public static WifiManager.WifiLock createWifiLock(Context context, String tag) { - WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); - return wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, tag); - } + intent.putExtra("track", song.getTitle()); + intent.putExtra("artist", song.getArtist()); + intent.putExtra("album", song.getAlbum()); + intent.putExtra("ListSize", (long) downloadService.getSongs().size()); + intent.putExtra("id", (long) downloadService.getCurrentPlayingIndex() + 1); + intent.putExtra("duration", (long) downloadService.getPlayerDuration()); + intent.putExtra("position", (long) downloadService.getPlayerPosition()); + intent.putExtra("coverart", albumArtFile.getAbsolutePath()); + intent.putExtra("package","net.nullsum.audinaut"); + } else { + intent.putExtra("track", ""); + intent.putExtra("artist", ""); + intent.putExtra("album", ""); + intent.putExtra("ListSize", (long) 0); + intent.putExtra("id", (long) 0); + intent.putExtra("duration", (long) 0); + intent.putExtra("position", (long) 0); + intent.putExtra("coverart", ""); + intent.putExtra("package","net.nullsum.audinaut"); + } + } - public static Random getRandom() { - if(random == null) { - random = new SecureRandom(); - } + public static WifiManager.WifiLock createWifiLock(Context context, String tag) { + WifiManager wm = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); + return wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, tag); + } - return random; - } + public static Random getRandom() { + if(random == null) { + random = new SecureRandom(); + } + + return random; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/tags/Bastp.java b/app/src/main/java/net/nullsum/audinaut/util/tags/Bastp.java index 425afd8..eb4adc3 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/tags/Bastp.java +++ b/app/src/main/java/net/nullsum/audinaut/util/tags/Bastp.java @@ -12,7 +12,7 @@ * 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 . + * along with this program. If not, see . */ @@ -24,62 +24,62 @@ import java.util.HashMap; public class Bastp { - - public Bastp() { - } - - public HashMap getTags(String fname) { - HashMap tags = new HashMap(); - try { - RandomAccessFile ra = new RandomAccessFile(fname, "r"); - tags = getTags(ra); - ra.close(); - } - catch(Exception e) { - /* we dont' care much: SOMETHING went wrong. d'oh! */ - } - - return tags; - } - - public HashMap getTags(RandomAccessFile s) { - HashMap tags = new HashMap(); - byte[] file_ff = new byte[4]; - - try { - s.read(file_ff); - String magic = new String(file_ff); - if(magic.equals("fLaC")) { - tags = (new FlacFile()).getTags(s); - } - else if(magic.equals("OggS")) { - tags = (new OggFile()).getTags(s); - } - else if(file_ff[0] == -1 && file_ff[1] == -5) { /* aka 0xfffb in real languages */ - tags = (new LameHeader()).getTags(s); - } - else if(magic.substring(0,3).equals("ID3")) { - tags = (new ID3v2File()).getTags(s); - if(tags.containsKey("_hdrlen")) { - Long hlen = Long.parseLong( tags.get("_hdrlen").toString(), 10 ); - HashMap lameInfo = (new LameHeader()).parseLameHeader(s, hlen); - /* add gain tags if not already present */ - inheritTag("REPLAYGAIN_TRACK_GAIN", lameInfo, tags); - inheritTag("REPLAYGAIN_ALBUM_GAIN", lameInfo, tags); - } - } - tags.put("_magic", magic); - } - catch (IOException e) { - } - return tags; - } - - private void inheritTag(String key, HashMap from, HashMap to) { - if(!to.containsKey(key) && from.containsKey(key)) { - to.put(key, from.get(key)); - } - } - + + public Bastp() { + } + + public HashMap getTags(String fname) { + HashMap tags = new HashMap(); + try { + RandomAccessFile ra = new RandomAccessFile(fname, "r"); + tags = getTags(ra); + ra.close(); + } + catch(Exception e) { + /* we dont' care much: SOMETHING went wrong. d'oh! */ + } + + return tags; + } + + public HashMap getTags(RandomAccessFile s) { + HashMap tags = new HashMap(); + byte[] file_ff = new byte[4]; + + try { + s.read(file_ff); + String magic = new String(file_ff); + if(magic.equals("fLaC")) { + tags = (new FlacFile()).getTags(s); + } + else if(magic.equals("OggS")) { + tags = (new OggFile()).getTags(s); + } + else if(file_ff[0] == -1 && file_ff[1] == -5) { /* aka 0xfffb in real languages */ + tags = (new LameHeader()).getTags(s); + } + else if(magic.substring(0,3).equals("ID3")) { + tags = (new ID3v2File()).getTags(s); + if(tags.containsKey("_hdrlen")) { + Long hlen = Long.parseLong( tags.get("_hdrlen").toString(), 10 ); + HashMap lameInfo = (new LameHeader()).parseLameHeader(s, hlen); + /* add gain tags if not already present */ + inheritTag("REPLAYGAIN_TRACK_GAIN", lameInfo, tags); + inheritTag("REPLAYGAIN_ALBUM_GAIN", lameInfo, tags); + } + } + tags.put("_magic", magic); + } + catch (IOException e) { + } + return tags; + } + + private void inheritTag(String key, HashMap from, HashMap to) { + if(!to.containsKey(key) && from.containsKey(key)) { + to.put(key, from.get(key)); + } + } + } diff --git a/app/src/main/java/net/nullsum/audinaut/util/tags/BastpUtil.java b/app/src/main/java/net/nullsum/audinaut/util/tags/BastpUtil.java index e5af115..269f837 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/tags/BastpUtil.java +++ b/app/src/main/java/net/nullsum/audinaut/util/tags/BastpUtil.java @@ -12,9 +12,9 @@ * 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 . + * along with this program. If not, see . */ - + package net.nullsum.audinaut.util.tags; import android.support.v4.util.LruCache; @@ -22,52 +22,52 @@ import java.util.HashMap; import java.util.Vector; public final class BastpUtil { - private static final RGLruCache rgCache = new RGLruCache(16); + private static final RGLruCache rgCache = new RGLruCache(16); - /** Returns the ReplayGain values of 'path' as - */ - public static float[] getReplayGainValues(String path) { - float[] cached = rgCache.get(path); + /** Returns the ReplayGain values of 'path' as + */ + public static float[] getReplayGainValues(String path) { + float[] cached = rgCache.get(path); - if(cached == null) { - cached = getReplayGainValuesFromFile(path); - rgCache.put(path, cached); - } - return cached; - } - - - - /** Parse given file and return track,album replay gain values - */ - private static float[] getReplayGainValuesFromFile(String path) { - String[] keys = { "REPLAYGAIN_TRACK_GAIN", "REPLAYGAIN_ALBUM_GAIN" }; - float[] adjust= { 0f , 0f }; - HashMap tags = (new Bastp()).getTags(path); - - for (int i=0; i { - public RGLruCache(int size) { - super(size); - } - } + if(cached == null) { + cached = getReplayGainValuesFromFile(path); + rgCache.put(path, cached); + } + return cached; + } + + + + /** Parse given file and return track,album replay gain values + */ + private static float[] getReplayGainValuesFromFile(String path) { + String[] keys = { "REPLAYGAIN_TRACK_GAIN", "REPLAYGAIN_ALBUM_GAIN" }; + float[] adjust= { 0f , 0f }; + HashMap tags = (new Bastp()).getTags(path); + + for (int i=0; i { + public RGLruCache(int size) { + super(size); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/util/tags/Common.java b/app/src/main/java/net/nullsum/audinaut/util/tags/Common.java index ed1c606..fa67271 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/tags/Common.java +++ b/app/src/main/java/net/nullsum/audinaut/util/tags/Common.java @@ -12,7 +12,7 @@ * 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 . + * along with this program. If not, see . */ @@ -24,88 +24,88 @@ import java.util.HashMap; import java.util.Vector; public class Common { - private static final long MAX_PKT_SIZE = 524288; - - public void xdie(String reason) throws IOException { - throw new IOException(reason); - } - - /* - ** Returns a 32bit int from given byte offset in LE - */ - public int b2le32(byte[] b, int off) { - int r = 0; - for(int i=0; i<4; i++) { - r |= ( b2u(b[off+i]) << (8*i) ); - } - return r; - } - - public int b2be32(byte[] b, int off) { - return swap32(b2le32(b, off)); - } - - public int swap32(int i) { - return((i&0xff)<<24)+((i&0xff00)<<8)+((i&0xff0000)>>8)+((i>>24)&0xff); - } - - /* - ** convert 'byte' value into unsigned int - */ - public int b2u(byte x) { - return (x & 0xFF); - } - - /* - ** Printout debug message to STDOUT - */ - public void debug(String s) { - System.out.println("DBUG "+s); - } - - public HashMap parse_vorbis_comment(RandomAccessFile s, long offset, long payload_len) throws IOException { - HashMap tags = new HashMap(); - int comments = 0; // number of found comments - int xoff = 0; // offset within 'scratch' - int can_read = (int)(payload_len > MAX_PKT_SIZE ? MAX_PKT_SIZE : payload_len); - byte[] scratch = new byte[can_read]; - - // seek to given position and slurp in the payload - s.seek(offset); - s.read(scratch); - - // skip vendor string in format: [LEN][VENDOR_STRING] - xoff += 4 + b2le32(scratch, xoff); // 4 = LEN = 32bit int - comments = b2le32(scratch, xoff); - xoff += 4; - - // debug("comments count = "+comments); - for(int i=0; i scratch.length) - xdie("string out of bounds"); - - String tag_raw = new String(scratch, xoff-clen, clen); - String[] tag_vec = tag_raw.split("=",2); - String tag_key = tag_vec[0].toUpperCase(); - - addTagEntry(tags, tag_key, tag_vec[1]); - } - return tags; - } - - public void addTagEntry(HashMap tags, String key, String value) { - if(tags.containsKey(key)) { - ((Vector)tags.get(key)).add(value); // just add to existing vector - } - else { - Vector vx = new Vector(); - vx.add(value); - tags.put(key, vx); - } - } - + private static final long MAX_PKT_SIZE = 524288; + + public void xdie(String reason) throws IOException { + throw new IOException(reason); + } + + /* + ** Returns a 32bit int from given byte offset in LE + */ + public int b2le32(byte[] b, int off) { + int r = 0; + for(int i=0; i<4; i++) { + r |= ( b2u(b[off+i]) << (8*i) ); + } + return r; + } + + public int b2be32(byte[] b, int off) { + return swap32(b2le32(b, off)); + } + + public int swap32(int i) { + return((i&0xff)<<24)+((i&0xff00)<<8)+((i&0xff0000)>>8)+((i>>24)&0xff); + } + + /* + ** convert 'byte' value into unsigned int + */ + public int b2u(byte x) { + return (x & 0xFF); + } + + /* + ** Printout debug message to STDOUT + */ + public void debug(String s) { + System.out.println("DBUG "+s); + } + + public HashMap parse_vorbis_comment(RandomAccessFile s, long offset, long payload_len) throws IOException { + HashMap tags = new HashMap(); + int comments = 0; // number of found comments + int xoff = 0; // offset within 'scratch' + int can_read = (int)(payload_len > MAX_PKT_SIZE ? MAX_PKT_SIZE : payload_len); + byte[] scratch = new byte[can_read]; + + // seek to given position and slurp in the payload + s.seek(offset); + s.read(scratch); + + // skip vendor string in format: [LEN][VENDOR_STRING] + xoff += 4 + b2le32(scratch, xoff); // 4 = LEN = 32bit int + comments = b2le32(scratch, xoff); + xoff += 4; + + // debug("comments count = "+comments); + for(int i=0; i scratch.length) + xdie("string out of bounds"); + + String tag_raw = new String(scratch, xoff-clen, clen); + String[] tag_vec = tag_raw.split("=",2); + String tag_key = tag_vec[0].toUpperCase(); + + addTagEntry(tags, tag_key, tag_vec[1]); + } + return tags; + } + + public void addTagEntry(HashMap tags, String key, String value) { + if(tags.containsKey(key)) { + ((Vector)tags.get(key)).add(value); // just add to existing vector + } + else { + Vector vx = new Vector(); + vx.add(value); + tags.put(key, vx); + } + } + } diff --git a/app/src/main/java/net/nullsum/audinaut/util/tags/FlacFile.java b/app/src/main/java/net/nullsum/audinaut/util/tags/FlacFile.java index 2d7db90..5793694 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/tags/FlacFile.java +++ b/app/src/main/java/net/nullsum/audinaut/util/tags/FlacFile.java @@ -12,7 +12,7 @@ * 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 . + * along with this program. If not, see . */ package net.nullsum.audinaut.util.tags; @@ -24,62 +24,62 @@ import java.util.Enumeration; public class FlacFile extends Common { - private static final int FLAC_TYPE_COMMENT = 4; // ID of 'VorbisComment's - - public FlacFile() { - } - - public HashMap getTags(RandomAccessFile s) throws IOException { - int xoff = 4; // skip file magic - int retry = 64; - int r[]; - HashMap tags = new HashMap(); - - for(; retry > 0; retry--) { - r = parse_metadata_block(s, xoff); - - if(r[2] == FLAC_TYPE_COMMENT) { - tags = parse_vorbis_comment(s, xoff+r[0], r[1]); - break; - } - - if(r[3] != 0) - break; // eof reached - - // else: calculate next offset - xoff += r[0] + r[1]; - } - return tags; - } - - /* Parses the metadata block at 'offset' and returns - ** [header_size, payload_size, type, stop_after] - */ - private int[] parse_metadata_block(RandomAccessFile s, long offset) throws IOException { - int[] result = new int[4]; - byte[] mb_head = new byte[4]; - int stop_after = 0; - int block_type = 0; - int block_size = 0; - - s.seek(offset); - - if( s.read(mb_head) != 4 ) - xdie("failed to read metadata block header"); - - block_size = b2be32(mb_head,0); // read whole header as 32 big endian - block_type = (block_size >> 24) & 127; // BIT 1-7 are the type - stop_after = (((block_size >> 24) & 128) > 0 ? 1 : 0 ); // BIT 0 indicates the last-block flag - block_size = (block_size & 0x00FFFFFF); // byte 1-7 are the size - - // debug("size="+block_size+", type="+block_type+", is_last="+stop_after); - - result[0] = 4; // hardcoded - only returned to be consistent with OGG parser - result[1] = block_size; - result[2] = block_type; - result[3] = stop_after; - - return result; - } - + private static final int FLAC_TYPE_COMMENT = 4; // ID of 'VorbisComment's + + public FlacFile() { + } + + public HashMap getTags(RandomAccessFile s) throws IOException { + int xoff = 4; // skip file magic + int retry = 64; + int r[]; + HashMap tags = new HashMap(); + + for(; retry > 0; retry--) { + r = parse_metadata_block(s, xoff); + + if(r[2] == FLAC_TYPE_COMMENT) { + tags = parse_vorbis_comment(s, xoff+r[0], r[1]); + break; + } + + if(r[3] != 0) + break; // eof reached + + // else: calculate next offset + xoff += r[0] + r[1]; + } + return tags; + } + + /* Parses the metadata block at 'offset' and returns + ** [header_size, payload_size, type, stop_after] + */ + private int[] parse_metadata_block(RandomAccessFile s, long offset) throws IOException { + int[] result = new int[4]; + byte[] mb_head = new byte[4]; + int stop_after = 0; + int block_type = 0; + int block_size = 0; + + s.seek(offset); + + if( s.read(mb_head) != 4 ) + xdie("failed to read metadata block header"); + + block_size = b2be32(mb_head,0); // read whole header as 32 big endian + block_type = (block_size >> 24) & 127; // BIT 1-7 are the type + stop_after = (((block_size >> 24) & 128) > 0 ? 1 : 0 ); // BIT 0 indicates the last-block flag + block_size = (block_size & 0x00FFFFFF); // byte 1-7 are the size + + // debug("size="+block_size+", type="+block_type+", is_last="+stop_after); + + result[0] = 4; // hardcoded - only returned to be consistent with OGG parser + result[1] = block_size; + result[2] = block_type; + result[3] = stop_after; + + return result; + } + } diff --git a/app/src/main/java/net/nullsum/audinaut/util/tags/ID3v2File.java b/app/src/main/java/net/nullsum/audinaut/util/tags/ID3v2File.java index 0af9ad4..f643e39 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/tags/ID3v2File.java +++ b/app/src/main/java/net/nullsum/audinaut/util/tags/ID3v2File.java @@ -12,7 +12,7 @@ * 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 . + * along with this program. If not, see . */ package net.nullsum.audinaut.util.tags; @@ -25,156 +25,156 @@ import java.util.Locale; public class ID3v2File extends Common { - private static int ID3_ENC_LATIN = 0x00; - private static int ID3_ENC_UTF16LE = 0x01; - private static int ID3_ENC_UTF16BE = 0x02; - private static int ID3_ENC_UTF8 = 0x03; - - public ID3v2File() { - } - - public HashMap getTags(RandomAccessFile s) throws IOException { - HashMap tags = new HashMap(); - - final int v2hdr_len = 10; - byte[] v2hdr = new byte[v2hdr_len]; - - // read the whole 10 byte header into memory - s.seek(0); - s.read(v2hdr); - - int id3v = ((b2be32(v2hdr,0))) & 0xFF; // swapped ID3\04 -> ver. ist the first byte - int v3len = ((b2be32(v2hdr,6))); // total size EXCLUDING the this 10 byte header - v3len = ((v3len & 0x7f000000) >> 3) | // for some funky reason, this is encoded as 7*4 bits - ((v3len & 0x007f0000) >> 2) | - ((v3len & 0x00007f00) >> 1) | - ((v3len & 0x0000007f) >> 0) ; - - // debug(">> tag version ID3v2."+id3v); - // debug(">> LEN= "+v3len+" // "+v3len); - - // we should already be at the first frame - // so we can start the parsing right now - tags = parse_v3_frames(s, v3len); - tags.put("_hdrlen", v3len+v2hdr_len); - return tags; - } - - /* Parses all ID3v2 frames at the current position up until payload_len - ** bytes were read - */ - public HashMap parse_v3_frames(RandomAccessFile s, long payload_len) throws IOException { - HashMap tags = new HashMap(); - byte[] frame = new byte[10]; // a frame header is always 10 bytes - long bread = 0; // total amount of read bytes - - while(bread < payload_len) { - bread += s.read(frame); - String framename = new String(frame, 0, 4); - int slen = b2be32(frame, 4); - - /* Abort on silly sizes */ - if(slen < 1 || slen > 524288) - break; - - byte[] xpl = new byte[slen]; - bread += s.read(xpl); + private static int ID3_ENC_LATIN = 0x00; + private static int ID3_ENC_UTF16LE = 0x01; + private static int ID3_ENC_UTF16BE = 0x02; + private static int ID3_ENC_UTF8 = 0x03; - if(framename.substring(0,1).equals("T")) { - String[] nmzInfo = normalizeTaginfo(framename, xpl); + public ID3v2File() { + } - for(int i = 0; i < nmzInfo.length; i += 2) { - String oggKey = nmzInfo[i]; - String decPld = nmzInfo[i + 1]; + public HashMap getTags(RandomAccessFile s) throws IOException { + HashMap tags = new HashMap(); - if (oggKey.length() > 0 && !tags.containsKey(oggKey)) { - addTagEntry(tags, oggKey, decPld); - } - } - } - else if(framename.equals("RVA2")) { - // - } - - } - return tags; - } - - /* Converts ID3v2 sillyframes to OggNames */ - private String[] normalizeTaginfo(String k, byte[] v) { - String[] rv = new String[] {"",""}; - HashMap lu = new HashMap(); - lu.put("TIT2", "TITLE"); - lu.put("TALB", "ALBUM"); - lu.put("TPE1", "ARTIST"); - - if(lu.containsKey(k)) { - /* A normal, known key: translate into Ogg-Frame name */ - rv[0] = (String)lu.get(k); - rv[1] = getDecodedString(v); - } - else if(k.equals("TXXX")) { - /* A freestyle field, ieks! */ - String txData[] = getDecodedString(v).split(Character.toString('\0'), 2); - /* Check if we got replaygain info in key\0value style */ - if(txData.length == 2) { - if(txData[0].matches("^(?i)REPLAYGAIN_(ALBUM|TRACK)_GAIN$")) { - rv[0] = txData[0].toUpperCase(); /* some tagwriters use lowercase for this */ - rv[1] = txData[1]; - } else { - // Check for replaygain tags just thrown randomly in field - int nextStartIndex = 1; - int startName = txData[1].toLowerCase(Locale.US).indexOf("replaygain_"); - ArrayList parts = new ArrayList(); - while(startName != -1) { - int endName = txData[1].indexOf((char) 0, startName); - if(endName != -1) { - parts.add(txData[1].substring(startName, endName).toUpperCase()); - int endValue = txData[1].indexOf((char) 0, endName + 1); - if(endValue != -1) { - parts.add(txData[1].substring(endName + 1, endValue)); - nextStartIndex = endValue + 1; - } else { - break; - } - } else { - break; - } + final int v2hdr_len = 10; + byte[] v2hdr = new byte[v2hdr_len]; - startName = txData[1].toLowerCase(Locale.US).indexOf("replaygain_", nextStartIndex); - } + // read the whole 10 byte header into memory + s.seek(0); + s.read(v2hdr); + + int id3v = ((b2be32(v2hdr,0))) & 0xFF; // swapped ID3\04 -> ver. ist the first byte + int v3len = ((b2be32(v2hdr,6))); // total size EXCLUDING the this 10 byte header + v3len = ((v3len & 0x7f000000) >> 3) | // for some funky reason, this is encoded as 7*4 bits + ((v3len & 0x007f0000) >> 2) | + ((v3len & 0x00007f00) >> 1) | + ((v3len & 0x0000007f) >> 0) ; + + // debug(">> tag version ID3v2."+id3v); + // debug(">> LEN= "+v3len+" // "+v3len); + + // we should already be at the first frame + // so we can start the parsing right now + tags = parse_v3_frames(s, v3len); + tags.put("_hdrlen", v3len+v2hdr_len); + return tags; + } + + /* Parses all ID3v2 frames at the current position up until payload_len + ** bytes were read + */ + public HashMap parse_v3_frames(RandomAccessFile s, long payload_len) throws IOException { + HashMap tags = new HashMap(); + byte[] frame = new byte[10]; // a frame header is always 10 bytes + long bread = 0; // total amount of read bytes + + while(bread < payload_len) { + bread += s.read(frame); + String framename = new String(frame, 0, 4); + int slen = b2be32(frame, 4); + + /* Abort on silly sizes */ + if(slen < 1 || slen > 524288) + break; + + byte[] xpl = new byte[slen]; + bread += s.read(xpl); + + if(framename.substring(0,1).equals("T")) { + String[] nmzInfo = normalizeTaginfo(framename, xpl); + + for(int i = 0; i < nmzInfo.length; i += 2) { + String oggKey = nmzInfo[i]; + String decPld = nmzInfo[i + 1]; + + if (oggKey.length() > 0 && !tags.containsKey(oggKey)) { + addTagEntry(tags, oggKey, decPld); + } + } + } + else if(framename.equals("RVA2")) { + // + } + + } + return tags; + } + + /* Converts ID3v2 sillyframes to OggNames */ + private String[] normalizeTaginfo(String k, byte[] v) { + String[] rv = new String[] {"",""}; + HashMap lu = new HashMap(); + lu.put("TIT2", "TITLE"); + lu.put("TALB", "ALBUM"); + lu.put("TPE1", "ARTIST"); + + if(lu.containsKey(k)) { + /* A normal, known key: translate into Ogg-Frame name */ + rv[0] = (String)lu.get(k); + rv[1] = getDecodedString(v); + } + else if(k.equals("TXXX")) { + /* A freestyle field, ieks! */ + String txData[] = getDecodedString(v).split(Character.toString('\0'), 2); + /* Check if we got replaygain info in key\0value style */ + if(txData.length == 2) { + if(txData[0].matches("^(?i)REPLAYGAIN_(ALBUM|TRACK)_GAIN$")) { + rv[0] = txData[0].toUpperCase(); /* some tagwriters use lowercase for this */ + rv[1] = txData[1]; + } else { + // Check for replaygain tags just thrown randomly in field + int nextStartIndex = 1; + int startName = txData[1].toLowerCase(Locale.US).indexOf("replaygain_"); + ArrayList parts = new ArrayList(); + while(startName != -1) { + int endName = txData[1].indexOf((char) 0, startName); + if(endName != -1) { + parts.add(txData[1].substring(startName, endName).toUpperCase()); + int endValue = txData[1].indexOf((char) 0, endName + 1); + if(endValue != -1) { + parts.add(txData[1].substring(endName + 1, endValue)); + nextStartIndex = endValue + 1; + } else { + break; + } + } else { + break; + } + + startName = txData[1].toLowerCase(Locale.US).indexOf("replaygain_", nextStartIndex); + } + + if(parts.size() > 0) { + rv = new String[parts.size()]; + rv = parts.toArray(rv); + } + } + } + } + + return rv; + } + + /* Converts a raw byte-stream text into a java String */ + private String getDecodedString(byte[] raw) { + int encid = raw[0] & 0xFF; + int len = raw.length; + String v = ""; + try { + if(encid == ID3_ENC_LATIN) { + v = new String(raw, 1, len-1, "ISO-8859-1"); + } + else if (encid == ID3_ENC_UTF8) { + v = new String(raw, 1, len-1, "UTF-8"); + } + else if (encid == ID3_ENC_UTF16LE) { + v = new String(raw, 3, len-3, "UTF-16LE"); + } + else if (encid == ID3_ENC_UTF16BE) { + v = new String(raw, 3, len-3, "UTF-16BE"); + } + } catch(Exception e) {} + return v; + } - if(parts.size() > 0) { - rv = new String[parts.size()]; - rv = parts.toArray(rv); - } - } - } - } - - return rv; - } - - /* Converts a raw byte-stream text into a java String */ - private String getDecodedString(byte[] raw) { - int encid = raw[0] & 0xFF; - int len = raw.length; - String v = ""; - try { - if(encid == ID3_ENC_LATIN) { - v = new String(raw, 1, len-1, "ISO-8859-1"); - } - else if (encid == ID3_ENC_UTF8) { - v = new String(raw, 1, len-1, "UTF-8"); - } - else if (encid == ID3_ENC_UTF16LE) { - v = new String(raw, 3, len-3, "UTF-16LE"); - } - else if (encid == ID3_ENC_UTF16BE) { - v = new String(raw, 3, len-3, "UTF-16BE"); - } - } catch(Exception e) {} - return v; - } - } diff --git a/app/src/main/java/net/nullsum/audinaut/util/tags/LameHeader.java b/app/src/main/java/net/nullsum/audinaut/util/tags/LameHeader.java index 4f293d3..d23f892 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/tags/LameHeader.java +++ b/app/src/main/java/net/nullsum/audinaut/util/tags/LameHeader.java @@ -12,7 +12,7 @@ * 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 . + * along with this program. If not, see . */ package net.nullsum.audinaut.util.tags; @@ -24,47 +24,47 @@ import java.util.Enumeration; public class LameHeader extends Common { - - public LameHeader() { - } - - public HashMap getTags(RandomAccessFile s) throws IOException { - return parseLameHeader(s, 0); - } - - public HashMap parseLameHeader(RandomAccessFile s, long offset) throws IOException { - HashMap tags = new HashMap(); - byte[] chunk = new byte[4]; - - s.seek(offset + 0x24); - s.read(chunk); - - String lameMark = new String(chunk, 0, chunk.length, "ISO-8859-1"); - - if(lameMark.equals("Info") || lameMark.equals("Xing")) { - s.seek(offset+0xAB); - s.read(chunk); - - int raw = b2be32(chunk, 0); - int gtrk_raw = raw >> 16; /* first 16 bits are the raw track gain value */ - int galb_raw = raw & 0xFFFF; /* the rest is for the album gain value */ - - float gtrk_val = (float)(gtrk_raw & 0x01FF)/10; - float galb_val = (float)(galb_raw & 0x01FF)/10; - - gtrk_val = ((gtrk_raw&0x0200)!=0 ? -1*gtrk_val : gtrk_val); - galb_val = ((galb_raw&0x0200)!=0 ? -1*galb_val : galb_val); - - if( (gtrk_raw&0xE000) == 0x2000 ) { - addTagEntry(tags, "REPLAYGAIN_TRACK_GAIN", gtrk_val+" dB"); - } - if( (gtrk_raw&0xE000) == 0x4000 ) { - addTagEntry(tags, "REPLAYGAIN_ALBUM_GAIN", galb_val+" dB"); - } - - } - - return tags; - } - + + public LameHeader() { + } + + public HashMap getTags(RandomAccessFile s) throws IOException { + return parseLameHeader(s, 0); + } + + public HashMap parseLameHeader(RandomAccessFile s, long offset) throws IOException { + HashMap tags = new HashMap(); + byte[] chunk = new byte[4]; + + s.seek(offset + 0x24); + s.read(chunk); + + String lameMark = new String(chunk, 0, chunk.length, "ISO-8859-1"); + + if(lameMark.equals("Info") || lameMark.equals("Xing")) { + s.seek(offset+0xAB); + s.read(chunk); + + int raw = b2be32(chunk, 0); + int gtrk_raw = raw >> 16; /* first 16 bits are the raw track gain value */ + int galb_raw = raw & 0xFFFF; /* the rest is for the album gain value */ + + float gtrk_val = (float)(gtrk_raw & 0x01FF)/10; + float galb_val = (float)(galb_raw & 0x01FF)/10; + + gtrk_val = ((gtrk_raw&0x0200)!=0 ? -1*gtrk_val : gtrk_val); + galb_val = ((galb_raw&0x0200)!=0 ? -1*galb_val : galb_val); + + if( (gtrk_raw&0xE000) == 0x2000 ) { + addTagEntry(tags, "REPLAYGAIN_TRACK_GAIN", gtrk_val+" dB"); + } + if( (gtrk_raw&0xE000) == 0x4000 ) { + addTagEntry(tags, "REPLAYGAIN_ALBUM_GAIN", galb_val+" dB"); + } + + } + + return tags; + } + } diff --git a/app/src/main/java/net/nullsum/audinaut/util/tags/OggFile.java b/app/src/main/java/net/nullsum/audinaut/util/tags/OggFile.java index 12b0984..847c1b2 100644 --- a/app/src/main/java/net/nullsum/audinaut/util/tags/OggFile.java +++ b/app/src/main/java/net/nullsum/audinaut/util/tags/OggFile.java @@ -12,7 +12,7 @@ * 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 . + * along with this program. If not, see . */ package net.nullsum.audinaut.util.tags; @@ -25,90 +25,90 @@ import java.util.HashMap; public class OggFile extends Common { - private static final int OGG_PAGE_SIZE = 27; // Static size of an OGG Page - private static final int OGG_TYPE_COMMENT = 3; // ID of 'VorbisComment's - - public OggFile() { - } - - public HashMap getTags(RandomAccessFile s) throws IOException { - long offset = 0; - int retry = 64; - HashMap tags = new HashMap(); - - for( ; retry > 0 ; retry-- ) { - long res[] = parse_ogg_page(s, offset); - if(res[2] == OGG_TYPE_COMMENT) { - tags = parse_ogg_vorbis_comment(s, offset+res[0], res[1]); - break; - } - offset += res[0] + res[1]; - } - return tags; - } - - - /* Parses the ogg page at offset 'offset' and returns - ** [header_size, payload_size, type] - */ - private long[] parse_ogg_page(RandomAccessFile s, long offset) throws IOException { - long[] result = new long[3]; // [header_size, payload_size] - byte[] p_header = new byte[OGG_PAGE_SIZE]; // buffer for the page header - byte[] scratch; - int bread = 0; // number of bytes read - int psize = 0; // payload-size - int nsegs = 0; // Number of segments - - s.seek(offset); - bread = s.read(p_header); - if(bread != OGG_PAGE_SIZE) - xdie("Unable to read() OGG_PAGE_HEADER"); - if((new String(p_header, 0, 5)).equals("OggS\0") != true) - xdie("Invalid magic - not an ogg file?"); - - nsegs = b2u(p_header[26]); - // debug("> file seg: "+nsegs); - if(nsegs > 0) { - scratch = new byte[nsegs]; - bread = s.read(scratch); - if(bread != nsegs) - xdie("Failed to read segtable"); - - for(int i=0; i pre-read */ - if(psize >= 1 && s.read(p_header, 0, 1) == 1) { - result[2] = b2u(p_header[0]); - } - - return result; - } - - /* In 'vorbiscomment' field is prefixed with \3vorbis in OGG files - ** we check that this marker is present and call the generic comment - ** parset with the correct offset (+7) */ - private HashMap parse_ogg_vorbis_comment(RandomAccessFile s, long offset, long pl_len) throws IOException { - final int pfx_len = 7; - byte[] pfx = new byte[pfx_len]; - - if(pl_len < pfx_len) - xdie("ogg vorbis comment field is too short!"); - - s.seek(offset); - s.read(pfx); - - if( (new String(pfx, 0, pfx_len)).equals("\3vorbis") == false ) - xdie("Damaged packet found!"); - - return parse_vorbis_comment(s, offset+pfx_len, pl_len-pfx_len); - } - + private static final int OGG_PAGE_SIZE = 27; // Static size of an OGG Page + private static final int OGG_TYPE_COMMENT = 3; // ID of 'VorbisComment's + + public OggFile() { + } + + public HashMap getTags(RandomAccessFile s) throws IOException { + long offset = 0; + int retry = 64; + HashMap tags = new HashMap(); + + for( ; retry > 0 ; retry-- ) { + long res[] = parse_ogg_page(s, offset); + if(res[2] == OGG_TYPE_COMMENT) { + tags = parse_ogg_vorbis_comment(s, offset+res[0], res[1]); + break; + } + offset += res[0] + res[1]; + } + return tags; + } + + + /* Parses the ogg page at offset 'offset' and returns + ** [header_size, payload_size, type] + */ + private long[] parse_ogg_page(RandomAccessFile s, long offset) throws IOException { + long[] result = new long[3]; // [header_size, payload_size] + byte[] p_header = new byte[OGG_PAGE_SIZE]; // buffer for the page header + byte[] scratch; + int bread = 0; // number of bytes read + int psize = 0; // payload-size + int nsegs = 0; // Number of segments + + s.seek(offset); + bread = s.read(p_header); + if(bread != OGG_PAGE_SIZE) + xdie("Unable to read() OGG_PAGE_HEADER"); + if((new String(p_header, 0, 5)).equals("OggS\0") != true) + xdie("Invalid magic - not an ogg file?"); + + nsegs = b2u(p_header[26]); + // debug("> file seg: "+nsegs); + if(nsegs > 0) { + scratch = new byte[nsegs]; + bread = s.read(scratch); + if(bread != nsegs) + xdie("Failed to read segtable"); + + for(int i=0; i pre-read */ + if(psize >= 1 && s.read(p_header, 0, 1) == 1) { + result[2] = b2u(p_header[0]); + } + + return result; + } + + /* In 'vorbiscomment' field is prefixed with \3vorbis in OGG files + ** we check that this marker is present and call the generic comment + ** parset with the correct offset (+7) */ + private HashMap parse_ogg_vorbis_comment(RandomAccessFile s, long offset, long pl_len) throws IOException { + final int pfx_len = 7; + byte[] pfx = new byte[pfx_len]; + + if(pl_len < pfx_len) + xdie("ogg vorbis comment field is too short!"); + + s.seek(offset); + s.read(pfx); + + if( (new String(pfx, 0, pfx_len)).equals("\3vorbis") == false ) + xdie("Damaged packet found!"); + + return parse_vorbis_comment(s, offset+pfx_len, pl_len-pfx_len); + } + }; diff --git a/app/src/main/java/net/nullsum/audinaut/view/AlbumView.java b/app/src/main/java/net/nullsum/audinaut/view/AlbumView.java index de8c759..faca80d 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/AlbumView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/AlbumView.java @@ -34,83 +34,83 @@ import net.nullsum.audinaut.util.Util; import java.io.File; public class AlbumView extends UpdateView2 { - private static final String TAG = AlbumView.class.getSimpleName(); + private static final String TAG = AlbumView.class.getSimpleName(); - private File file; - private TextView titleView; - private TextView artistView; - private boolean showArtist = true; - private String coverArtId; + private File file; + private TextView titleView; + private TextView artistView; + private boolean showArtist = true; + private String coverArtId; - public AlbumView(Context context, boolean cell) { - super(context); + public AlbumView(Context context, boolean cell) { + super(context); - if(cell) { - LayoutInflater.from(context).inflate(R.layout.album_cell_item, this, true); - } else { - LayoutInflater.from(context).inflate(R.layout.album_list_item, this, true); - } + if(cell) { + LayoutInflater.from(context).inflate(R.layout.album_cell_item, this, true); + } else { + LayoutInflater.from(context).inflate(R.layout.album_list_item, this, true); + } - coverArtView = findViewById(R.id.album_coverart); - titleView = (TextView) findViewById(R.id.album_title); - artistView = (TextView) findViewById(R.id.album_artist); + coverArtView = findViewById(R.id.album_coverart); + titleView = (TextView) findViewById(R.id.album_title); + artistView = (TextView) findViewById(R.id.album_artist); - moreButton = (ImageView) findViewById(R.id.item_more); + moreButton = (ImageView) findViewById(R.id.item_more); - checkable = true; - } + checkable = true; + } - public void setShowArtist(boolean showArtist) { - this.showArtist = showArtist; - } + public void setShowArtist(boolean showArtist) { + this.showArtist = showArtist; + } - protected void setObjectImpl(MusicDirectory.Entry album, ImageLoader imageLoader) { - titleView.setText(album.getAlbumDisplay()); - String artist = ""; - if(showArtist) { - artist = album.getArtist(); - if (artist == null) { - artist = ""; - } - if (album.getYear() != null) { - artist += " - " + album.getYear(); - } - } else if(album.getYear() != null) { - artist += album.getYear(); - } - artistView.setText(album.getArtist() == null ? "" : artist); - onUpdateImageView(); - file = null; - } + protected void setObjectImpl(MusicDirectory.Entry album, ImageLoader imageLoader) { + titleView.setText(album.getAlbumDisplay()); + String artist = ""; + if(showArtist) { + artist = album.getArtist(); + if (artist == null) { + artist = ""; + } + if (album.getYear() != null) { + artist += " - " + album.getYear(); + } + } else if(album.getYear() != null) { + artist += album.getYear(); + } + artistView.setText(album.getArtist() == null ? "" : artist); + onUpdateImageView(); + file = null; + } - public void onUpdateImageView() { - imageTask = item2.loadImage(coverArtView, item, false, true); - coverArtId = item.getCoverArt(); - } + public void onUpdateImageView() { + imageTask = item2.loadImage(coverArtView, item, false, true); + coverArtId = item.getCoverArt(); + } - @Override - protected void updateBackground() { - if(file == null) { - file = FileUtil.getAlbumDirectory(context, item); - } + @Override + protected void updateBackground() { + if(file == null) { + file = FileUtil.getAlbumDirectory(context, item); + } - exists = file.exists(); - } + exists = file.exists(); + } - @Override - public void update() { - super.update(); + @Override + public void update() { + super.update(); - if(!Util.equals(item.getCoverArt(), coverArtId)) { - onUpdateImageView(); - } - } + if(!Util.equals(item.getCoverArt(), coverArtId)) { + onUpdateImageView(); + } + } - public MusicDirectory.Entry getEntry() { - return item; - } + public MusicDirectory.Entry getEntry() { + return item; + } - public File getFile() { - return file; - } + public File getFile() { + return file; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/ArtistEntryView.java b/app/src/main/java/net/nullsum/audinaut/view/ArtistEntryView.java index 99e180a..41c4605 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/ArtistEntryView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/ArtistEntryView.java @@ -35,9 +35,9 @@ import java.io.File; * @author Sindre Mehus */ public class ArtistEntryView extends UpdateView { - private static final String TAG = ArtistEntryView.class.getSimpleName(); + private static final String TAG = ArtistEntryView.class.getSimpleName(); - private File file; + private File file; private TextView titleView; public ArtistEntryView(Context context) { @@ -45,25 +45,25 @@ public class ArtistEntryView extends UpdateView { LayoutInflater.from(context).inflate(R.layout.basic_list_item, this, true); titleView = (TextView) findViewById(R.id.item_name); - moreButton = (ImageView) findViewById(R.id.item_more); - moreButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - v.showContextMenu(); - } - }); + moreButton = (ImageView) findViewById(R.id.item_more); + moreButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + v.showContextMenu(); + } + }); } - - protected void setObjectImpl(MusicDirectory.Entry artist) { - titleView.setText(artist.getTitle()); - file = FileUtil.getArtistDirectory(context, artist); - } - - @Override - protected void updateBackground() { - exists = file.exists(); - } - public File getFile() { - return file; - } + protected void setObjectImpl(MusicDirectory.Entry artist) { + titleView.setText(artist.getTitle()); + file = FileUtil.getArtistDirectory(context, artist); + } + + @Override + protected void updateBackground() { + exists = file.exists(); + } + + public File getFile() { + return file; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/ArtistView.java b/app/src/main/java/net/nullsum/audinaut/view/ArtistView.java index b8535bc..9cd2851 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/ArtistView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/ArtistView.java @@ -36,9 +36,9 @@ import java.io.File; * @author Sindre Mehus */ public class ArtistView extends UpdateView { - private static final String TAG = ArtistView.class.getSimpleName(); + private static final String TAG = ArtistView.class.getSimpleName(); - private File file; + private File file; private TextView titleView; public ArtistView(Context context) { @@ -46,25 +46,25 @@ public class ArtistView extends UpdateView { LayoutInflater.from(context).inflate(R.layout.basic_list_item, this, true); titleView = (TextView) findViewById(R.id.item_name); - moreButton = (ImageView) findViewById(R.id.item_more); - moreButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View v) { - v.showContextMenu(); - } - }); + moreButton = (ImageView) findViewById(R.id.item_more); + moreButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + v.showContextMenu(); + } + }); } - - protected void setObjectImpl(Artist artist) { - titleView.setText(artist.getName()); - file = FileUtil.getArtistDirectory(context, artist); - } - - @Override - protected void updateBackground() { - exists = file.exists(); - } - public File getFile() { - return file; - } + protected void setObjectImpl(Artist artist) { + titleView.setText(artist.getName()); + file = FileUtil.getArtistDirectory(context, artist); + } + + @Override + protected void updateBackground() { + exists = file.exists(); + } + + public File getFile() { + return file; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/AutoRepeatButton.java b/app/src/main/java/net/nullsum/audinaut/view/AutoRepeatButton.java index 66f93be..0ce4113 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/AutoRepeatButton.java +++ b/app/src/main/java/net/nullsum/audinaut/view/AutoRepeatButton.java @@ -8,79 +8,79 @@ import android.view.View; public class AutoRepeatButton extends AppCompatImageButton { - private static final long initialRepeatDelay = 1000; - private static final long repeatIntervalInMilliseconds = 300; - private boolean doClick = true; - private Runnable repeatEvent = null; + private static final long initialRepeatDelay = 1000; + private static final long repeatIntervalInMilliseconds = 300; + private boolean doClick = true; + private Runnable repeatEvent = null; - private Runnable repeatClickWhileButtonHeldRunnable = new Runnable() { - @Override - public void run() { - doClick = false; - //Perform the present repetition of the click action provided by the user - // in setOnClickListener(). - if(repeatEvent != null) - repeatEvent.run(); + private Runnable repeatClickWhileButtonHeldRunnable = new Runnable() { + @Override + public void run() { + doClick = false; + //Perform the present repetition of the click action provided by the user + // in setOnClickListener(). + if(repeatEvent != null) + repeatEvent.run(); - //Schedule the next repetitions of the click action, using a faster repeat - // interval than the initial repeat delay interval. - postDelayed(repeatClickWhileButtonHeldRunnable, repeatIntervalInMilliseconds); - } - }; + //Schedule the next repetitions of the click action, using a faster repeat + // interval than the initial repeat delay interval. + postDelayed(repeatClickWhileButtonHeldRunnable, repeatIntervalInMilliseconds); + } + }; - private void commonConstructorCode() { - this.setOnTouchListener(new OnTouchListener() { - @Override - public boolean onTouch(View v, MotionEvent event) { - int action = event.getAction(); - if(action == MotionEvent.ACTION_DOWN) - { - doClick = true; - //Just to be sure that we removed all callbacks, - // which should have occurred in the ACTION_UP - removeCallbacks(repeatClickWhileButtonHeldRunnable); + private void commonConstructorCode() { + this.setOnTouchListener(new OnTouchListener() { + @Override + public boolean onTouch(View v, MotionEvent event) { + int action = event.getAction(); + if(action == MotionEvent.ACTION_DOWN) + { + doClick = true; + //Just to be sure that we removed all callbacks, + // which should have occurred in the ACTION_UP + removeCallbacks(repeatClickWhileButtonHeldRunnable); - //Schedule the start of repetitions after a one half second delay. - postDelayed(repeatClickWhileButtonHeldRunnable, initialRepeatDelay); - - setPressed(true); - } - else if(action == MotionEvent.ACTION_UP) { - //Cancel any repetition in progress. - removeCallbacks(repeatClickWhileButtonHeldRunnable); + //Schedule the start of repetitions after a one half second delay. + postDelayed(repeatClickWhileButtonHeldRunnable, initialRepeatDelay); - if(doClick || repeatEvent == null) { - performClick(); - } - - setPressed(false); - } + setPressed(true); + } + else if(action == MotionEvent.ACTION_UP) { + //Cancel any repetition in progress. + removeCallbacks(repeatClickWhileButtonHeldRunnable); - //Returning true here prevents performClick() from getting called - // in the usual manner, which would be redundant, given that we are - // already calling it above. - return true; - } - }); - } - - public void setOnRepeatListener(Runnable runnable) { - repeatEvent = runnable; - } + if(doClick || repeatEvent == null) { + performClick(); + } - public AutoRepeatButton(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - commonConstructorCode(); - } + setPressed(false); + } + + //Returning true here prevents performClick() from getting called + // in the usual manner, which would be redundant, given that we are + // already calling it above. + return true; + } + }); + } + + public void setOnRepeatListener(Runnable runnable) { + repeatEvent = runnable; + } + + public AutoRepeatButton(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + commonConstructorCode(); + } - public AutoRepeatButton(Context context, AttributeSet attrs) { - super(context, attrs); - commonConstructorCode(); - } + public AutoRepeatButton(Context context, AttributeSet attrs) { + super(context, attrs); + commonConstructorCode(); + } - public AutoRepeatButton(Context context) { - super(context); - commonConstructorCode(); - } + public AutoRepeatButton(Context context) { + super(context); + commonConstructorCode(); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/BasicHeaderView.java b/app/src/main/java/net/nullsum/audinaut/view/BasicHeaderView.java index 873d406..0454b5e 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/BasicHeaderView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/BasicHeaderView.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.view; @@ -22,19 +22,19 @@ import android.widget.TextView; import net.nullsum.audinaut.R; public class BasicHeaderView extends UpdateView { - TextView nameView; + TextView nameView; - public BasicHeaderView(Context context) { - this(context, R.layout.basic_header); - } - public BasicHeaderView(Context context, int layout) { - super(context, false); + public BasicHeaderView(Context context) { + this(context, R.layout.basic_header); + } + public BasicHeaderView(Context context, int layout) { + super(context, false); - LayoutInflater.from(context).inflate(layout, this, true); - nameView = (TextView) findViewById(R.id.item_name); - } + LayoutInflater.from(context).inflate(layout, this, true); + nameView = (TextView) findViewById(R.id.item_name); + } - protected void setObjectImpl(String string) { - nameView.setText(string); - } + protected void setObjectImpl(String string) { + nameView.setText(string); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/BasicListView.java b/app/src/main/java/net/nullsum/audinaut/view/BasicListView.java index 7c70422..c908c1a 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/BasicListView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/BasicListView.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.view; @@ -25,18 +25,18 @@ import android.widget.TextView; import net.nullsum.audinaut.R; public class BasicListView extends UpdateView { - private TextView titleView; + private TextView titleView; - public BasicListView(Context context) { - super(context, false); - LayoutInflater.from(context).inflate(R.layout.basic_list_item, this, true); + public BasicListView(Context context) { + super(context, false); + LayoutInflater.from(context).inflate(R.layout.basic_list_item, this, true); - titleView = (TextView) findViewById(R.id.item_name); - moreButton = (ImageView) findViewById(R.id.item_more); - moreButton.setVisibility(View.GONE); - } + titleView = (TextView) findViewById(R.id.item_name); + moreButton = (ImageView) findViewById(R.id.item_more); + moreButton.setVisibility(View.GONE); + } - protected void setObjectImpl(String string) { - titleView.setText(string); - } + protected void setObjectImpl(String string) { + titleView.setText(string); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/CardView.java b/app/src/main/java/net/nullsum/audinaut/view/CardView.java index 9cc1f34..4f69c2f 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/CardView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/CardView.java @@ -14,46 +14,46 @@ import net.nullsum.audinaut.R; import net.nullsum.audinaut.util.DrawableTint; public class CardView extends FrameLayout{ - private static final String TAG = CardView.class.getSimpleName(); + private static final String TAG = CardView.class.getSimpleName(); - public CardView(Context context) { - super(context); - init(context); - } + public CardView(Context context) { + super(context); + init(context); + } - public CardView(Context context, AttributeSet attrs) { - super(context, attrs); - init(context); - } + public CardView(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } - public CardView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(context); - } + public CardView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + init(context); + } - public CardView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - init(context); - } + public CardView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(context); + } - @Override - public void onDraw(Canvas canvas) { - try { - Path clipPath = new Path(); - float roundedDp = getResources().getDimension(R.dimen.Card_Radius); - clipPath.addRoundRect(new RectF(canvas.getClipBounds()), roundedDp, roundedDp, Path.Direction.CW); - canvas.clipPath(clipPath); - } catch(Exception e) { - Log.e(TAG, "Failed to clip path on canvas", e); - } - super.onDraw(canvas); - } + @Override + public void onDraw(Canvas canvas) { + try { + Path clipPath = new Path(); + float roundedDp = getResources().getDimension(R.dimen.Card_Radius); + clipPath.addRoundRect(new RectF(canvas.getClipBounds()), roundedDp, roundedDp, Path.Direction.CW); + canvas.clipPath(clipPath); + } catch(Exception e) { + Log.e(TAG, "Failed to clip path on canvas", e); + } + super.onDraw(canvas); + } - private void init(Context context) { - setClipChildren(true); - setBackgroundResource(DrawableTint.getDrawableRes(context, R.attr.cardBackgroundDrawable)); - if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { - setElevation(getResources().getInteger(R.integer.Card_Elevation)); - } - } + private void init(Context context) { + setClipChildren(true); + setBackgroundResource(DrawableTint.getDrawableRes(context, R.attr.cardBackgroundDrawable)); + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + setElevation(getResources().getInteger(R.integer.Card_Elevation)); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/ErrorDialog.java b/app/src/main/java/net/nullsum/audinaut/view/ErrorDialog.java index 389ebdd..4447f57 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/ErrorDialog.java +++ b/app/src/main/java/net/nullsum/audinaut/view/ErrorDialog.java @@ -60,16 +60,16 @@ public class ErrorDialog { } }); - try { - builder.create().show(); - } catch(Exception e) { - // Don't care, just means no activity to attach to - } + try { + builder.create().show(); + } catch(Exception e) { + // Don't care, just means no activity to attach to + } + } + + private void restart(Activity activity) { + Intent intent = new Intent(activity, SubsonicFragmentActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + Util.startActivityWithoutTransition(activity, intent); } - - private void restart(Activity activity) { - Intent intent = new Intent(activity, SubsonicFragmentActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - Util.startActivityWithoutTransition(activity, intent); - } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/FastScroller.java b/app/src/main/java/net/nullsum/audinaut/view/FastScroller.java index 5c8e29c..9cf9b2d 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/FastScroller.java +++ b/app/src/main/java/net/nullsum/audinaut/view/FastScroller.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.view; @@ -39,297 +39,297 @@ import net.nullsum.audinaut.R; import static android.support.v7.widget.RecyclerView.OnScrollListener; public class FastScroller extends LinearLayout { - private static final String TAG = FastScroller.class.getSimpleName(); - private static final int BUBBLE_ANIMATION_DURATION = 100; - private static final int TRACK_SNAP_RANGE = 5; + private static final String TAG = FastScroller.class.getSimpleName(); + private static final int BUBBLE_ANIMATION_DURATION = 100; + private static final int TRACK_SNAP_RANGE = 5; - private TextView bubble; - private View handle; - private RecyclerView recyclerView; - private final ScrollListener scrollListener = new ScrollListener(); - private int height; - private int visibleRange = -1; - private RecyclerView.Adapter adapter; - private AdapterDataObserver adapterObserver; - private boolean visibleBubble = true; - private boolean hasScrolled = false; + private TextView bubble; + private View handle; + private RecyclerView recyclerView; + private final ScrollListener scrollListener = new ScrollListener(); + private int height; + private int visibleRange = -1; + private RecyclerView.Adapter adapter; + private AdapterDataObserver adapterObserver; + private boolean visibleBubble = true; + private boolean hasScrolled = false; - private ObjectAnimator currentAnimator = null; + private ObjectAnimator currentAnimator = null; - public FastScroller(final Context context,final AttributeSet attrs,final int defStyleAttr) { - super(context,attrs,defStyleAttr); - initialise(context); - } + public FastScroller(final Context context,final AttributeSet attrs,final int defStyleAttr) { + super(context,attrs,defStyleAttr); + initialise(context); + } - public FastScroller(final Context context) { - super(context); - initialise(context); - } + public FastScroller(final Context context) { + super(context); + initialise(context); + } - public FastScroller(final Context context,final AttributeSet attrs) { - super(context, attrs); - initialise(context); - } + public FastScroller(final Context context,final AttributeSet attrs) { + super(context, attrs); + initialise(context); + } - private void initialise(Context context) { - setOrientation(HORIZONTAL); - setClipChildren(false); - LayoutInflater inflater = LayoutInflater.from(context); - inflater.inflate(R.layout.fast_scroller,this,true); - bubble = (TextView)findViewById(R.id.fastscroller_bubble); - handle = findViewById(R.id.fastscroller_handle); - bubble.setVisibility(INVISIBLE); - setVisibility(GONE); - } + private void initialise(Context context) { + setOrientation(HORIZONTAL); + setClipChildren(false); + LayoutInflater inflater = LayoutInflater.from(context); + inflater.inflate(R.layout.fast_scroller,this,true); + bubble = (TextView)findViewById(R.id.fastscroller_bubble); + handle = findViewById(R.id.fastscroller_handle); + bubble.setVisibility(INVISIBLE); + setVisibility(GONE); + } - @Override - protected void onSizeChanged(int w,int h,int oldw,int oldh) { - super.onSizeChanged(w,h,oldw,oldh); - height = h; - visibleRange = -1; - } + @Override + protected void onSizeChanged(int w,int h,int oldw,int oldh) { + super.onSizeChanged(w,h,oldw,oldh); + height = h; + visibleRange = -1; + } - @Override - public boolean onTouchEvent(@NonNull MotionEvent event) { - final int action = event.getAction(); - switch(action) - { - case MotionEvent.ACTION_DOWN: - if(event.getX() < (handle.getX() - 30)) { - return false; - } + @Override + public boolean onTouchEvent(@NonNull MotionEvent event) { + final int action = event.getAction(); + switch(action) + { + case MotionEvent.ACTION_DOWN: + if(event.getX() < (handle.getX() - 30)) { + return false; + } - if(currentAnimator != null) - currentAnimator.cancel(); - if(bubble.getVisibility() == INVISIBLE) { - if(visibleBubble) { - showBubble(); - } - } else if(!visibleBubble) { - hideBubble(); - } - handle.setSelected(true); - case MotionEvent.ACTION_MOVE: - setRecyclerViewPosition(event.getY()); - return true; - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - handle.setSelected(false); - hideBubble(); - return true; - } - return super.onTouchEvent(event); - } + if(currentAnimator != null) + currentAnimator.cancel(); + if(bubble.getVisibility() == INVISIBLE) { + if(visibleBubble) { + showBubble(); + } + } else if(!visibleBubble) { + hideBubble(); + } + handle.setSelected(true); + case MotionEvent.ACTION_MOVE: + setRecyclerViewPosition(event.getY()); + return true; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + handle.setSelected(false); + hideBubble(); + return true; + } + return super.onTouchEvent(event); + } - public void attachRecyclerView(RecyclerView recyclerView) { - this.recyclerView = recyclerView; - recyclerView.addOnScrollListener(scrollListener); - registerAdapter(); - visibleRange = -1; - } - public void detachRecyclerView() { - recyclerView.removeOnScrollListener(scrollListener); - recyclerView.setVerticalScrollBarEnabled(true); - unregisterAdapter(); - recyclerView = null; - setVisibility(View.GONE); - } - public boolean isAttached() { - return recyclerView != null; - } + public void attachRecyclerView(RecyclerView recyclerView) { + this.recyclerView = recyclerView; + recyclerView.addOnScrollListener(scrollListener); + registerAdapter(); + visibleRange = -1; + } + public void detachRecyclerView() { + recyclerView.removeOnScrollListener(scrollListener); + recyclerView.setVerticalScrollBarEnabled(true); + unregisterAdapter(); + recyclerView = null; + setVisibility(View.GONE); + } + public boolean isAttached() { + return recyclerView != null; + } - private void setRecyclerViewPosition(float y) { - if(recyclerView != null) { - if(recyclerView.getChildCount() == 0) { - return; - } + private void setRecyclerViewPosition(float y) { + if(recyclerView != null) { + if(recyclerView.getChildCount() == 0) { + return; + } - int itemCount = recyclerView.getAdapter().getItemCount(); - float proportion = getValueInRange(0, 1f, y / (float) height); + int itemCount = recyclerView.getAdapter().getItemCount(); + float proportion = getValueInRange(0, 1f, y / (float) height); - float targetPosFloat = getValueInRange(0, itemCount - 1, proportion * (float)itemCount); - int targetPos = (int) targetPosFloat; + float targetPosFloat = getValueInRange(0, itemCount - 1, proportion * (float)itemCount); + int targetPos = (int) targetPosFloat; - // Immediately make sure that the target is visible - LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); - // layoutManager.scrollToPositionWithOffset(targetPos, 0); - View firstVisibleView = recyclerView.getChildAt(0); + // Immediately make sure that the target is visible + LinearLayoutManager layoutManager = (LinearLayoutManager) recyclerView.getLayoutManager(); + // layoutManager.scrollToPositionWithOffset(targetPos, 0); + View firstVisibleView = recyclerView.getChildAt(0); - // Calculate how far through this position we are - int columns = Math.round(recyclerView.getWidth() / firstVisibleView.getWidth()); - int firstVisiblePosition = recyclerView.getChildPosition(firstVisibleView); - int remainder = (targetPos - firstVisiblePosition) % columns; - float offsetPercentage = (targetPosFloat - targetPos + remainder) / columns; - if(offsetPercentage < 0) { - offsetPercentage = 1 + offsetPercentage; - } - int firstVisibleHeight = firstVisibleView.getHeight(); - if(columns > 1) { - firstVisibleHeight += (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, GridSpacingDecoration.SPACING, firstVisibleView.getResources().getDisplayMetrics()); - } - int offset = (int) (offsetPercentage * firstVisibleHeight); + // Calculate how far through this position we are + int columns = Math.round(recyclerView.getWidth() / firstVisibleView.getWidth()); + int firstVisiblePosition = recyclerView.getChildPosition(firstVisibleView); + int remainder = (targetPos - firstVisiblePosition) % columns; + float offsetPercentage = (targetPosFloat - targetPos + remainder) / columns; + if(offsetPercentage < 0) { + offsetPercentage = 1 + offsetPercentage; + } + int firstVisibleHeight = firstVisibleView.getHeight(); + if(columns > 1) { + firstVisibleHeight += (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, GridSpacingDecoration.SPACING, firstVisibleView.getResources().getDisplayMetrics()); + } + int offset = (int) (offsetPercentage * firstVisibleHeight); - layoutManager.scrollToPositionWithOffset(targetPos, -offset); - onUpdateScroll(1, 1); + layoutManager.scrollToPositionWithOffset(targetPos, -offset); + onUpdateScroll(1, 1); - try { - String bubbleText = null; - RecyclerView.Adapter adapter = recyclerView.getAdapter(); - if(adapter instanceof BubbleTextGetter) { - bubbleText = ((BubbleTextGetter) adapter).getTextToShowInBubble(targetPos); - } + try { + String bubbleText = null; + RecyclerView.Adapter adapter = recyclerView.getAdapter(); + if(adapter instanceof BubbleTextGetter) { + bubbleText = ((BubbleTextGetter) adapter).getTextToShowInBubble(targetPos); + } - if(bubbleText == null) { - visibleBubble = false; - bubble.setVisibility(View.INVISIBLE); - } else { - bubble.setText(bubbleText); - bubble.setVisibility(View.VISIBLE); - visibleBubble = true; - } - } catch(Exception e) { - Log.e(TAG, "Error getting text for bubble", e); - } - } - } + if(bubbleText == null) { + visibleBubble = false; + bubble.setVisibility(View.INVISIBLE); + } else { + bubble.setText(bubbleText); + bubble.setVisibility(View.VISIBLE); + visibleBubble = true; + } + } catch(Exception e) { + Log.e(TAG, "Error getting text for bubble", e); + } + } + } - private float getValueInRange(float min, float max, float value) { - float minimum = Math.max(min, value); - return Math.min(minimum,max); - } + private float getValueInRange(float min, float max, float value) { + float minimum = Math.max(min, value); + return Math.min(minimum,max); + } - private void setBubbleAndHandlePosition(float y) { - int bubbleHeight = bubble.getHeight(); - int handleHeight = handle.getHeight(); - handle.setY(getValueInRange(0,height-handleHeight,(int)(y-handleHeight/2))); - bubble.setY(getValueInRange(0, height - bubbleHeight - handleHeight / 2, (int) (y - bubbleHeight))); - } + private void setBubbleAndHandlePosition(float y) { + int bubbleHeight = bubble.getHeight(); + int handleHeight = handle.getHeight(); + handle.setY(getValueInRange(0,height-handleHeight,(int)(y-handleHeight/2))); + bubble.setY(getValueInRange(0, height - bubbleHeight - handleHeight / 2, (int) (y - bubbleHeight))); + } - private void showBubble() { - bubble.setVisibility(VISIBLE); - if(currentAnimator != null) - currentAnimator.cancel(); - currentAnimator = ObjectAnimator.ofFloat(bubble,"alpha",0f,1f).setDuration(BUBBLE_ANIMATION_DURATION); - currentAnimator.start(); - } + private void showBubble() { + bubble.setVisibility(VISIBLE); + if(currentAnimator != null) + currentAnimator.cancel(); + currentAnimator = ObjectAnimator.ofFloat(bubble,"alpha",0f,1f).setDuration(BUBBLE_ANIMATION_DURATION); + currentAnimator.start(); + } - private void hideBubble() { - if(currentAnimator != null) - currentAnimator.cancel(); - currentAnimator = ObjectAnimator.ofFloat(bubble,"alpha",1f,0f).setDuration(BUBBLE_ANIMATION_DURATION); - currentAnimator.addListener(new AnimatorListenerAdapter(){ - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - bubble.setVisibility(INVISIBLE); - currentAnimator = null; - } + private void hideBubble() { + if(currentAnimator != null) + currentAnimator.cancel(); + currentAnimator = ObjectAnimator.ofFloat(bubble,"alpha",1f,0f).setDuration(BUBBLE_ANIMATION_DURATION); + currentAnimator.addListener(new AnimatorListenerAdapter(){ + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + bubble.setVisibility(INVISIBLE); + currentAnimator = null; + } - @Override - public void onAnimationCancel(Animator animation) { - super.onAnimationCancel(animation); - bubble.setVisibility(INVISIBLE); - currentAnimator = null; - } - }); - currentAnimator.start(); - } + @Override + public void onAnimationCancel(Animator animation) { + super.onAnimationCancel(animation); + bubble.setVisibility(INVISIBLE); + currentAnimator = null; + } + }); + currentAnimator.start(); + } - private void registerAdapter() { - RecyclerView.Adapter newAdapter = recyclerView.getAdapter(); - if(newAdapter != adapter) { - unregisterAdapter(); - } + private void registerAdapter() { + RecyclerView.Adapter newAdapter = recyclerView.getAdapter(); + if(newAdapter != adapter) { + unregisterAdapter(); + } - if(newAdapter != null) { - adapterObserver = new AdapterDataObserver() { - @Override - public void onChanged() { - visibleRange = -1; - } + if(newAdapter != null) { + adapterObserver = new AdapterDataObserver() { + @Override + public void onChanged() { + visibleRange = -1; + } - @Override - public void onItemRangeChanged(int positionStart, int itemCount) { - visibleRange = -1; - } + @Override + public void onItemRangeChanged(int positionStart, int itemCount) { + visibleRange = -1; + } - @Override - public void onItemRangeInserted(int positionStart, int itemCount) { - visibleRange = -1; - } + @Override + public void onItemRangeInserted(int positionStart, int itemCount) { + visibleRange = -1; + } - @Override - public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { - visibleRange = -1; - } + @Override + public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { + visibleRange = -1; + } - @Override - public void onItemRangeRemoved(int positionStart, int itemCount) { - visibleRange = -1; - } - }; - newAdapter.registerAdapterDataObserver(adapterObserver); - adapter = newAdapter; - } - } - private void unregisterAdapter() { - if(adapter != null) { - adapter.unregisterAdapterDataObserver(adapterObserver); - adapter = null; - adapterObserver = null; - } - } + @Override + public void onItemRangeRemoved(int positionStart, int itemCount) { + visibleRange = -1; + } + }; + newAdapter.registerAdapterDataObserver(adapterObserver); + adapter = newAdapter; + } + } + private void unregisterAdapter() { + if(adapter != null) { + adapter.unregisterAdapterDataObserver(adapterObserver); + adapter = null; + adapterObserver = null; + } + } - private class ScrollListener extends OnScrollListener { - @Override - public void onScrolled(RecyclerView rv,int dx,int dy) { - onUpdateScroll(dx, dy); - } - } + private class ScrollListener extends OnScrollListener { + @Override + public void onScrolled(RecyclerView rv,int dx,int dy) { + onUpdateScroll(dx, dy); + } + } - private void onUpdateScroll(int dx, int dy) { - if(recyclerView.getWidth() == 0) { - return; - } - registerAdapter(); + private void onUpdateScroll(int dx, int dy) { + if(recyclerView.getWidth() == 0) { + return; + } + registerAdapter(); - View firstVisibleView = recyclerView.getChildAt(0); - if(firstVisibleView == null) { - return; - } - int firstVisiblePosition = recyclerView.getChildPosition(firstVisibleView); + View firstVisibleView = recyclerView.getChildAt(0); + if(firstVisibleView == null) { + return; + } + int firstVisiblePosition = recyclerView.getChildPosition(firstVisibleView); - int itemCount = recyclerView.getAdapter().getItemCount(); - int columns = Math.round(recyclerView.getWidth() / firstVisibleView.getWidth()); - if(visibleRange == -1) { - visibleRange = recyclerView.getChildCount(); - } + int itemCount = recyclerView.getAdapter().getItemCount(); + int columns = Math.round(recyclerView.getWidth() / firstVisibleView.getWidth()); + if(visibleRange == -1) { + visibleRange = recyclerView.getChildCount(); + } - // Add the percentage of the item the user has scrolled past already - float pastFirst = -firstVisibleView.getY() / firstVisibleView.getHeight() * columns; - float position = firstVisiblePosition + pastFirst; + // Add the percentage of the item the user has scrolled past already + float pastFirst = -firstVisibleView.getY() / firstVisibleView.getHeight() * columns; + float position = firstVisiblePosition + pastFirst; - // Scale this so as we move down the visible range gets added to position from 0 -> visible range - float scaledVisibleRange = position / (float) (itemCount - visibleRange) * visibleRange; - position += scaledVisibleRange; + // Scale this so as we move down the visible range gets added to position from 0 -> visible range + float scaledVisibleRange = position / (float) (itemCount - visibleRange) * visibleRange; + position += scaledVisibleRange; - float proportion = position / itemCount; - setBubbleAndHandlePosition(height * proportion); + float proportion = position / itemCount; + setBubbleAndHandlePosition(height * proportion); - if((visibleRange * 2) < itemCount) { - if (!hasScrolled && (dx > 0 || dy > 0)) { - setVisibility(View.VISIBLE); - hasScrolled = true; - recyclerView.setVerticalScrollBarEnabled(false); - } - } else if(hasScrolled) { - setVisibility(View.GONE); - hasScrolled = false; - recyclerView.setVerticalScrollBarEnabled(true); - } - } + if((visibleRange * 2) < itemCount) { + if (!hasScrolled && (dx > 0 || dy > 0)) { + setVisibility(View.VISIBLE); + hasScrolled = true; + recyclerView.setVerticalScrollBarEnabled(false); + } + } else if(hasScrolled) { + setVisibility(View.GONE); + hasScrolled = false; + recyclerView.setVerticalScrollBarEnabled(true); + } + } - public interface BubbleTextGetter { - String getTextToShowInBubble(int position); - } + public interface BubbleTextGetter { + String getTextToShowInBubble(int position); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/GenreView.java b/app/src/main/java/net/nullsum/audinaut/view/GenreView.java index a69518a..bd28fe3 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/GenreView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/GenreView.java @@ -26,32 +26,32 @@ import net.nullsum.audinaut.R; import net.nullsum.audinaut.domain.Genre; public class GenreView extends UpdateView { - private static final String TAG = GenreView.class.getSimpleName(); + private static final String TAG = GenreView.class.getSimpleName(); - private TextView titleView; - private TextView songsView; - private TextView albumsView; + private TextView titleView; + private TextView songsView; + private TextView albumsView; - public GenreView(Context context) { - super(context, false); - LayoutInflater.from(context).inflate(R.layout.genre_list_item, this, true); + public GenreView(Context context) { + super(context, false); + LayoutInflater.from(context).inflate(R.layout.genre_list_item, this, true); - titleView = (TextView) findViewById(R.id.genre_name); - songsView = (TextView) findViewById(R.id.genre_songs); - albumsView = (TextView) findViewById(R.id.genre_albums); - } + titleView = (TextView) findViewById(R.id.genre_name); + songsView = (TextView) findViewById(R.id.genre_songs); + albumsView = (TextView) findViewById(R.id.genre_albums); + } - public void setObjectImpl(Genre genre) { - titleView.setText(genre.getName()); + public void setObjectImpl(Genre genre) { + titleView.setText(genre.getName()); - if(genre.getAlbumCount() != 0) { - songsView.setVisibility(View.VISIBLE); - albumsView.setVisibility(View.VISIBLE); - songsView.setText(context.getResources().getString(R.string.select_genre_songs, genre.getSongCount())); - albumsView.setText(context.getResources().getString(R.string.select_genre_albums, genre.getAlbumCount())); - } else { - songsView.setVisibility(View.GONE); - albumsView.setVisibility(View.GONE); - } - } + if(genre.getAlbumCount() != 0) { + songsView.setVisibility(View.VISIBLE); + albumsView.setVisibility(View.VISIBLE); + songsView.setText(context.getResources().getString(R.string.select_genre_songs, genre.getSongCount())); + albumsView.setText(context.getResources().getString(R.string.select_genre_albums, genre.getAlbumCount())); + } else { + songsView.setVisibility(View.GONE); + albumsView.setVisibility(View.GONE); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/GridSpacingDecoration.java b/app/src/main/java/net/nullsum/audinaut/view/GridSpacingDecoration.java index 8a60d9b..078ce8a 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/GridSpacingDecoration.java +++ b/app/src/main/java/net/nullsum/audinaut/view/GridSpacingDecoration.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.view; @@ -28,106 +28,106 @@ import android.widget.LinearLayout; import static android.widget.LinearLayout.*; public class GridSpacingDecoration extends RecyclerView.ItemDecoration { - private static final String TAG = GridSpacingDecoration.class.getSimpleName(); - public static final int SPACING = 10; + private static final String TAG = GridSpacingDecoration.class.getSimpleName(); + public static final int SPACING = 10; - @Override - public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { - super.getItemOffsets(outRect, view, parent, state); + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + super.getItemOffsets(outRect, view, parent, state); - int spacing = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, SPACING, view.getResources().getDisplayMetrics()); - int halfSpacing = spacing / 2; + int spacing = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, SPACING, view.getResources().getDisplayMetrics()); + int halfSpacing = spacing / 2; - int childCount = parent.getChildCount(); - int childIndex = parent.getChildPosition(view); - // Not an actual child (ie: during delete event) - if(childIndex == -1) { - return; - } - int spanCount = getTotalSpan(view, parent); - int spanIndex = childIndex % spanCount; + int childCount = parent.getChildCount(); + int childIndex = parent.getChildPosition(view); + // Not an actual child (ie: during delete event) + if(childIndex == -1) { + return; + } + int spanCount = getTotalSpan(view, parent); + int spanIndex = childIndex % spanCount; - // If we can, use the SpanSizeLookup since headers screw up the index calculation - RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); - if(layoutManager instanceof GridLayoutManager) { - GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager; - GridLayoutManager.SpanSizeLookup spanSizeLookup = gridLayoutManager.getSpanSizeLookup(); - if(spanSizeLookup != null) { - spanIndex = spanSizeLookup.getSpanIndex(childIndex, spanCount); - } - } - int spanSize = getSpanSize(parent, childIndex); + // If we can, use the SpanSizeLookup since headers screw up the index calculation + RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); + if(layoutManager instanceof GridLayoutManager) { + GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager; + GridLayoutManager.SpanSizeLookup spanSizeLookup = gridLayoutManager.getSpanSizeLookup(); + if(spanSizeLookup != null) { + spanIndex = spanSizeLookup.getSpanIndex(childIndex, spanCount); + } + } + int spanSize = getSpanSize(parent, childIndex); /* INVALID SPAN */ - if (spanCount < 1 || spanSize > 1) return; + if (spanCount < 1 || spanSize > 1) return; - int margins = 0; - if(view instanceof UpdateView) { - View firstChild = ((ViewGroup) view).getChildAt(0); - ViewGroup.LayoutParams layoutParams = firstChild.getLayoutParams(); - if (layoutParams instanceof LinearLayout.LayoutParams) { - margins = ((LinearLayout.LayoutParams) layoutParams).bottomMargin; - } else if (layoutParams instanceof FrameLayout.LayoutParams) { - margins = ((FrameLayout.LayoutParams) layoutParams).bottomMargin; - } - } - int doubleMargins = margins * 2; + int margins = 0; + if(view instanceof UpdateView) { + View firstChild = ((ViewGroup) view).getChildAt(0); + ViewGroup.LayoutParams layoutParams = firstChild.getLayoutParams(); + if (layoutParams instanceof LinearLayout.LayoutParams) { + margins = ((LinearLayout.LayoutParams) layoutParams).bottomMargin; + } else if (layoutParams instanceof FrameLayout.LayoutParams) { + margins = ((FrameLayout.LayoutParams) layoutParams).bottomMargin; + } + } + int doubleMargins = margins * 2; - outRect.top = halfSpacing - margins; - outRect.bottom = halfSpacing - margins; - outRect.left = halfSpacing - margins; - outRect.right = halfSpacing - margins; + outRect.top = halfSpacing - margins; + outRect.bottom = halfSpacing - margins; + outRect.left = halfSpacing - margins; + outRect.right = halfSpacing - margins; - if (isTopEdge(childIndex, spanIndex, spanCount)) { - outRect.top = spacing - doubleMargins; - } + if (isTopEdge(childIndex, spanIndex, spanCount)) { + outRect.top = spacing - doubleMargins; + } - if (isLeftEdge(spanIndex, spanCount)) { - outRect.left = spacing - doubleMargins; - } + if (isLeftEdge(spanIndex, spanCount)) { + outRect.left = spacing - doubleMargins; + } - if (isRightEdge(spanIndex, spanCount)) { - outRect.right = spacing - doubleMargins; - } + if (isRightEdge(spanIndex, spanCount)) { + outRect.right = spacing - doubleMargins; + } - if (isBottomEdge(childIndex, childCount, spanCount)) { - outRect.bottom = spacing - doubleMargins; - } - } + if (isBottomEdge(childIndex, childCount, spanCount)) { + outRect.bottom = spacing - doubleMargins; + } + } - protected int getTotalSpan(View view, RecyclerView parent) { - RecyclerView.LayoutManager mgr = parent.getLayoutManager(); - if (mgr instanceof GridLayoutManager) { - return ((GridLayoutManager) mgr).getSpanCount(); - } + protected int getTotalSpan(View view, RecyclerView parent) { + RecyclerView.LayoutManager mgr = parent.getLayoutManager(); + if (mgr instanceof GridLayoutManager) { + return ((GridLayoutManager) mgr).getSpanCount(); + } - return -1; - } - protected int getSpanSize(RecyclerView parent, int childIndex) { - RecyclerView.LayoutManager mgr = parent.getLayoutManager(); - if (mgr instanceof GridLayoutManager) { - GridLayoutManager.SpanSizeLookup lookup = ((GridLayoutManager) mgr).getSpanSizeLookup(); - if(lookup != null) { - return lookup.getSpanSize(childIndex); - } - } + return -1; + } + protected int getSpanSize(RecyclerView parent, int childIndex) { + RecyclerView.LayoutManager mgr = parent.getLayoutManager(); + if (mgr instanceof GridLayoutManager) { + GridLayoutManager.SpanSizeLookup lookup = ((GridLayoutManager) mgr).getSpanSizeLookup(); + if(lookup != null) { + return lookup.getSpanSize(childIndex); + } + } - return 1; - } + return 1; + } - protected boolean isLeftEdge(int spanIndex, int spanCount) { - return spanIndex == 0; - } + protected boolean isLeftEdge(int spanIndex, int spanCount) { + return spanIndex == 0; + } - protected boolean isRightEdge(int spanIndex, int spanCount) { - return spanIndex == spanCount - 1; - } + protected boolean isRightEdge(int spanIndex, int spanCount) { + return spanIndex == spanCount - 1; + } - protected boolean isTopEdge(int childIndex, int spanIndex, int spanCount) { - return childIndex < spanCount && childIndex == spanIndex; - } + protected boolean isTopEdge(int childIndex, int spanIndex, int spanCount) { + return childIndex < spanCount && childIndex == spanIndex; + } - protected boolean isBottomEdge(int childIndex, int childCount, int spanCount) { - return childIndex >= childCount - spanCount; - } + protected boolean isBottomEdge(int childIndex, int childCount, int spanCount) { + return childIndex >= childCount - spanCount; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/MyLeadingMarginSpan2.java b/app/src/main/java/net/nullsum/audinaut/view/MyLeadingMarginSpan2.java index 1823aee..d40e30c 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/MyLeadingMarginSpan2.java +++ b/app/src/main/java/net/nullsum/audinaut/view/MyLeadingMarginSpan2.java @@ -9,26 +9,26 @@ import android.text.style.LeadingMarginSpan; * Created by Scott on 1/13/2015. */ public class MyLeadingMarginSpan2 implements LeadingMarginSpan.LeadingMarginSpan2 { - private int margin; - private int lines; + private int margin; + private int lines; - public MyLeadingMarginSpan2(int lines, int margin) { - this.margin = margin; - this.lines = lines; - } + public MyLeadingMarginSpan2(int lines, int margin) { + this.margin = margin; + this.lines = lines; + } - @Override - public int getLeadingMargin(boolean first) { - return first ? margin : 0; - } + @Override + public int getLeadingMargin(boolean first) { + return first ? margin : 0; + } - @Override - public int getLeadingMarginLineCount() { - return lines; - } + @Override + public int getLeadingMarginLineCount() { + return lines; + } - @Override - public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, - int top, int baseline, int bottom, CharSequence text, - int start, int end, boolean first, Layout layout) {} + @Override + public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, + int top, int baseline, int bottom, CharSequence text, + int start, int end, boolean first, Layout layout) {} } diff --git a/app/src/main/java/net/nullsum/audinaut/view/PlaylistSongView.java b/app/src/main/java/net/nullsum/audinaut/view/PlaylistSongView.java index bdf955b..3cc6bb1 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/PlaylistSongView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/PlaylistSongView.java @@ -34,62 +34,62 @@ import net.nullsum.audinaut.util.FileUtil; import net.nullsum.audinaut.util.Util; public class PlaylistSongView extends UpdateView2> { - private static final String TAG = PlaylistSongView.class.getSimpleName(); + private static final String TAG = PlaylistSongView.class.getSimpleName(); - private TextView titleView; - private TextView countView; - private int count = 0; + private TextView titleView; + private TextView countView; + private int count = 0; - public PlaylistSongView(Context context) { - super(context, false); - this.context = context; - LayoutInflater.from(context).inflate(R.layout.basic_count_item, this, true); + public PlaylistSongView(Context context) { + super(context, false); + this.context = context; + LayoutInflater.from(context).inflate(R.layout.basic_count_item, this, true); - titleView = (TextView) findViewById(R.id.basic_count_name); - countView = (TextView) findViewById(R.id.basic_count_count); - } + titleView = (TextView) findViewById(R.id.basic_count_name); + countView = (TextView) findViewById(R.id.basic_count_count); + } - protected void setObjectImpl(Playlist playlist, List songs) { - count = 0; - titleView.setText(playlist.getName()); - // Make sure to hide initially so it's not present briefly before update - countView.setVisibility(View.GONE); - } + protected void setObjectImpl(Playlist playlist, List songs) { + count = 0; + titleView.setText(playlist.getName()); + // Make sure to hide initially so it's not present briefly before update + countView.setVisibility(View.GONE); + } - @Override - protected void updateBackground() { - // Make sure to reset when starting count - count = 0; - - // Don't try to lookup playlist for Create New - if(!"-1".equals(item.getId())) { - MusicDirectory cache = FileUtil.deserialize(context, Util.getCacheName(context, "playlist", item.getId()), MusicDirectory.class); - if(cache != null) { - // Try to find song instances in the given playlists - for(MusicDirectory.Entry song: item2) { - if(cache.getChildren().contains(song)) { - count++; - } - } - } - } - } + @Override + protected void updateBackground() { + // Make sure to reset when starting count + count = 0; - @Override - protected void update() { - // Update count display with appropriate information - if(count <= 0) { - countView.setVisibility(View.GONE); - } else { - String displayName; - if(count < 10) { - displayName = "0" + count; - } else { - displayName = "" + count; - } + // Don't try to lookup playlist for Create New + if(!"-1".equals(item.getId())) { + MusicDirectory cache = FileUtil.deserialize(context, Util.getCacheName(context, "playlist", item.getId()), MusicDirectory.class); + if(cache != null) { + // Try to find song instances in the given playlists + for(MusicDirectory.Entry song: item2) { + if(cache.getChildren().contains(song)) { + count++; + } + } + } + } + } - countView.setText(displayName); - countView.setVisibility(View.VISIBLE); - } - } + @Override + protected void update() { + // Update count display with appropriate information + if(count <= 0) { + countView.setVisibility(View.GONE); + } else { + String displayName; + if(count < 10) { + displayName = "0" + count; + } else { + displayName = "" + count; + } + + countView.setText(displayName); + countView.setVisibility(View.VISIBLE); + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/PlaylistView.java b/app/src/main/java/net/nullsum/audinaut/view/PlaylistView.java index 310779b..24f27cf 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/PlaylistView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/PlaylistView.java @@ -34,33 +34,33 @@ import net.nullsum.audinaut.util.SyncUtil; * @author Sindre Mehus */ public class PlaylistView extends UpdateView { - private static final String TAG = PlaylistView.class.getSimpleName(); + private static final String TAG = PlaylistView.class.getSimpleName(); - private TextView titleView; - private ImageLoader imageLoader; + private TextView titleView; + private ImageLoader imageLoader; - public PlaylistView(Context context, ImageLoader imageLoader, boolean largeCell) { - super(context); - LayoutInflater.from(context).inflate(largeCell ? R.layout.basic_cell_item : R.layout.basic_art_item, this, true); + public PlaylistView(Context context, ImageLoader imageLoader, boolean largeCell) { + super(context); + LayoutInflater.from(context).inflate(largeCell ? R.layout.basic_cell_item : R.layout.basic_art_item, this, true); - coverArtView = findViewById(R.id.item_art); - titleView = (TextView) findViewById(R.id.item_name); - moreButton = (ImageView) findViewById(R.id.item_more); + coverArtView = findViewById(R.id.item_art); + titleView = (TextView) findViewById(R.id.item_name); + moreButton = (ImageView) findViewById(R.id.item_more); - this.imageLoader = imageLoader; - } + this.imageLoader = imageLoader; + } - protected void setObjectImpl(Playlist playlist) { - titleView.setText(playlist.getName()); - imageTask = imageLoader.loadImage(coverArtView, playlist, false, true); - } + protected void setObjectImpl(Playlist playlist) { + titleView.setText(playlist.getName()); + imageTask = imageLoader.loadImage(coverArtView, playlist, false, true); + } - public void onUpdateImageView() { - imageTask = imageLoader.loadImage(coverArtView, item, false, true); - } + public void onUpdateImageView() { + imageTask = imageLoader.loadImage(coverArtView, item, false, true); + } - @Override - protected void updateBackground() { - pinned = SyncUtil.isSyncedPlaylist(context, item.getId()); - } + @Override + protected void updateBackground() { + pinned = SyncUtil.isSyncedPlaylist(context, item.getId()); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/RecyclingImageView.java b/app/src/main/java/net/nullsum/audinaut/view/RecyclingImageView.java index d3797a7..5216c62 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/RecyclingImageView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/RecyclingImageView.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2015 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2015 (C) Scott Jackson */ package net.nullsum.audinaut.view; @@ -26,90 +26,90 @@ import android.support.v7.widget.AppCompatImageView; import android.util.AttributeSet; public class RecyclingImageView extends AppCompatImageView { - private boolean invalidated = false; - private OnInvalidated onInvalidated; + private boolean invalidated = false; + private OnInvalidated onInvalidated; - public RecyclingImageView(Context context) { - super(context); - } + public RecyclingImageView(Context context) { + super(context); + } - public RecyclingImageView(Context context, AttributeSet attrs) { - super(context, attrs); - } + public RecyclingImageView(Context context, AttributeSet attrs) { + super(context, attrs); + } - public RecyclingImageView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - } + public RecyclingImageView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } - @Override - public void onDraw(Canvas canvas) { - Drawable drawable = this.getDrawable(); - if(drawable != null) { - if(drawable instanceof BitmapDrawable) { - if (isBitmapRecycled(drawable)) { - this.setImageDrawable(null); - setInvalidated(true); - } - } else if(drawable instanceof TransitionDrawable) { - TransitionDrawable transitionDrawable = (TransitionDrawable) drawable; + @Override + public void onDraw(Canvas canvas) { + Drawable drawable = this.getDrawable(); + if(drawable != null) { + if(drawable instanceof BitmapDrawable) { + if (isBitmapRecycled(drawable)) { + this.setImageDrawable(null); + setInvalidated(true); + } + } else if(drawable instanceof TransitionDrawable) { + TransitionDrawable transitionDrawable = (TransitionDrawable) drawable; - // If last bitmap in chain is recycled, just blank this out since it would be invalid anyways - Drawable lastDrawable = transitionDrawable.getDrawable(transitionDrawable.getNumberOfLayers() - 1); - if(isBitmapRecycled(lastDrawable)) { - this.setImageDrawable(null); - setInvalidated(true); - } else { - // Go through earlier bitmaps and make sure that they are not recycled - for (int i = 0; i < transitionDrawable.getNumberOfLayers(); i++) { - Drawable layerDrawable = transitionDrawable.getDrawable(i); - if (isBitmapRecycled(layerDrawable)) { - // If anything in the chain is broken, just get rid of transition and go to last drawable - this.setImageDrawable(lastDrawable); - break; - } - } - } - } - } + // If last bitmap in chain is recycled, just blank this out since it would be invalid anyways + Drawable lastDrawable = transitionDrawable.getDrawable(transitionDrawable.getNumberOfLayers() - 1); + if(isBitmapRecycled(lastDrawable)) { + this.setImageDrawable(null); + setInvalidated(true); + } else { + // Go through earlier bitmaps and make sure that they are not recycled + for (int i = 0; i < transitionDrawable.getNumberOfLayers(); i++) { + Drawable layerDrawable = transitionDrawable.getDrawable(i); + if (isBitmapRecycled(layerDrawable)) { + // If anything in the chain is broken, just get rid of transition and go to last drawable + this.setImageDrawable(lastDrawable); + break; + } + } + } + } + } - super.onDraw(canvas); - } + super.onDraw(canvas); + } - @Override - public void setImageDrawable(Drawable drawable) { - super.setImageDrawable(drawable); - setInvalidated(false); - } + @Override + public void setImageDrawable(Drawable drawable) { + super.setImageDrawable(drawable); + setInvalidated(false); + } - private boolean isBitmapRecycled(Drawable drawable) { - if(!(drawable instanceof BitmapDrawable)) { - return false; - } + private boolean isBitmapRecycled(Drawable drawable) { + if(!(drawable instanceof BitmapDrawable)) { + return false; + } - BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; - if (bitmapDrawable.getBitmap() != null && bitmapDrawable.getBitmap().isRecycled()) { - return true; - } else { - return false; - } - } + BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; + if (bitmapDrawable.getBitmap() != null && bitmapDrawable.getBitmap().isRecycled()) { + return true; + } else { + return false; + } + } - public void setInvalidated(boolean invalidated) { - this.invalidated = invalidated; + public void setInvalidated(boolean invalidated) { + this.invalidated = invalidated; - if(invalidated && onInvalidated != null) { - onInvalidated.onInvalidated(this); - } - } - public boolean isInvalidated() { - return invalidated; - } + if(invalidated && onInvalidated != null) { + onInvalidated.onInvalidated(this); + } + } + public boolean isInvalidated() { + return invalidated; + } - public void setOnInvalidated(OnInvalidated onInvalidated) { - this.onInvalidated = onInvalidated; - } + public void setOnInvalidated(OnInvalidated onInvalidated) { + this.onInvalidated = onInvalidated; + } - public interface OnInvalidated { - void onInvalidated(RecyclingImageView imageView); - } + public interface OnInvalidated { + void onInvalidated(RecyclingImageView imageView); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/SeekBarPreference.java b/app/src/main/java/net/nullsum/audinaut/view/SeekBarPreference.java index 997c102..89b0255 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/SeekBarPreference.java +++ b/app/src/main/java/net/nullsum/audinaut/view/SeekBarPreference.java @@ -38,121 +38,121 @@ import net.nullsum.audinaut.util.Constants; * SeekBar preference to set the shake force threshold. */ public class SeekBarPreference extends DialogPreference implements SeekBar.OnSeekBarChangeListener { - private static final String TAG = SeekBarPreference.class.getSimpleName(); - /** - * The current value. - */ - private String mValue; - private int mMin; - private int mMax; - private float mStepSize; - private String mDisplay; + private static final String TAG = SeekBarPreference.class.getSimpleName(); + /** + * The current value. + */ + private String mValue; + private int mMin; + private int mMax; + private float mStepSize; + private String mDisplay; - /** - * Our context (needed for getResources()) - */ - private Context mContext; + /** + * Our context (needed for getResources()) + */ + private Context mContext; - /** - * TextView to display current threshold. - */ - private TextView mValueText; + /** + * TextView to display current threshold. + */ + private TextView mValueText; - public SeekBarPreference(Context context, AttributeSet attrs) - { - super(context, attrs); - mContext = context; + public SeekBarPreference(Context context, AttributeSet attrs) + { + super(context, attrs); + mContext = context; - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SeekBarPreference); - mMin = a.getInteger(R.styleable.SeekBarPreference_min, 0); - mMax = a.getInteger(R.styleable.SeekBarPreference_max, 100); - mStepSize = a.getFloat(R.styleable.SeekBarPreference_stepSize, 1f); - mDisplay = a.getString(R.styleable.SeekBarPreference_display); - if(mDisplay == null) { - mDisplay = "%.0f"; - } + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SeekBarPreference); + mMin = a.getInteger(R.styleable.SeekBarPreference_min, 0); + mMax = a.getInteger(R.styleable.SeekBarPreference_max, 100); + mStepSize = a.getFloat(R.styleable.SeekBarPreference_stepSize, 1f); + mDisplay = a.getString(R.styleable.SeekBarPreference_display); + if(mDisplay == null) { + mDisplay = "%.0f"; + } a.recycle(); - } + } - @Override - public CharSequence getSummary() - { - return getSummary(mValue); - } + @Override + public CharSequence getSummary() + { + return getSummary(mValue); + } - @Override - protected Object onGetDefaultValue(TypedArray a, int index) - { - return a.getString(index); - } + @Override + protected Object onGetDefaultValue(TypedArray a, int index) + { + return a.getString(index); + } - @Override - protected void onSetInitialValue(boolean restoreValue, Object defaultValue) - { - mValue = restoreValue ? getPersistedString((String) defaultValue) : (String)defaultValue; - } + @Override + protected void onSetInitialValue(boolean restoreValue, Object defaultValue) + { + mValue = restoreValue ? getPersistedString((String) defaultValue) : (String)defaultValue; + } - /** - * Create the summary for the given value. - * - * @param value The force threshold. - * @return A string representation of the threshold. - */ - private String getSummary(String value) { - try { - int val = Integer.parseInt(value); - return String.format(mDisplay, (val + mMin) / mStepSize); - } catch (Exception e) { - return ""; - } - } + /** + * Create the summary for the given value. + * + * @param value The force threshold. + * @return A string representation of the threshold. + */ + private String getSummary(String value) { + try { + int val = Integer.parseInt(value); + return String.format(mDisplay, (val + mMin) / mStepSize); + } catch (Exception e) { + return ""; + } + } - @Override - protected View onCreateDialogView() - { - View view = super.onCreateDialogView(); + @Override + protected View onCreateDialogView() + { + View view = super.onCreateDialogView(); - mValueText = (TextView)view.findViewById(R.id.value); - mValueText.setText(getSummary(mValue)); + mValueText = (TextView)view.findViewById(R.id.value); + mValueText.setText(getSummary(mValue)); - SeekBar seekBar = (SeekBar)view.findViewById(R.id.seek_bar); - seekBar.setMax(mMax - mMin); - try { - seekBar.setProgress(Integer.parseInt(mValue)); - } catch(Exception e) { - seekBar.setProgress(0); - } - seekBar.setOnSeekBarChangeListener(this); + SeekBar seekBar = (SeekBar)view.findViewById(R.id.seek_bar); + seekBar.setMax(mMax - mMin); + try { + seekBar.setProgress(Integer.parseInt(mValue)); + } catch(Exception e) { + seekBar.setProgress(0); + } + seekBar.setOnSeekBarChangeListener(this); - return view; - } + return view; + } - @Override - protected void onDialogClosed(boolean positiveResult) - { - if(positiveResult) { - persistString(mValue); - notifyChanged(); - } - } + @Override + protected void onDialogClosed(boolean positiveResult) + { + if(positiveResult) { + persistString(mValue); + notifyChanged(); + } + } - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) - { - if (fromUser) { - mValue = String.valueOf(progress); - mValueText.setText(getSummary(mValue)); - } - } + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) + { + if (fromUser) { + mValue = String.valueOf(progress); + mValueText.setText(getSummary(mValue)); + } + } - @Override - public void onStartTrackingTouch(SeekBar seekBar) - { - } + @Override + public void onStartTrackingTouch(SeekBar seekBar) + { + } - @Override - public void onStopTrackingTouch(SeekBar seekBar) - { - } + @Override + public void onStopTrackingTouch(SeekBar seekBar) + { + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/SettingView.java b/app/src/main/java/net/nullsum/audinaut/view/SettingView.java index b4d3fe4..5645345 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/SettingView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/SettingView.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.view; @@ -28,61 +28,61 @@ import net.nullsum.audinaut.domain.User.MusicFolderSetting; import static net.nullsum.audinaut.domain.User.Setting; public class SettingView extends UpdateView2 { - private final TextView titleView; - private final CheckBox checkBox; + private final TextView titleView; + private final CheckBox checkBox; - public SettingView(Context context) { - super(context, false); - this.context = context; - LayoutInflater.from(context).inflate(R.layout.basic_choice_item, this, true); + public SettingView(Context context) { + super(context, false); + this.context = context; + LayoutInflater.from(context).inflate(R.layout.basic_choice_item, this, true); - titleView = (TextView) findViewById(R.id.item_name); - checkBox = (CheckBox) findViewById(R.id.item_checkbox); - checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { - @Override - public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { - if(item != null) { - item.setValue(isChecked); - } - } - }); - checkBox.setClickable(false); - } + titleView = (TextView) findViewById(R.id.item_name); + checkBox = (CheckBox) findViewById(R.id.item_checkbox); + checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if(item != null) { + item.setValue(isChecked); + } + } + }); + checkBox.setClickable(false); + } - protected void setObjectImpl(Setting setting, Boolean isEditable) { - // Can't edit non-role parts - String name = setting.getName(); - if(name.indexOf("Role") == -1 && !(setting instanceof MusicFolderSetting)) { - item2 = false; - } - - int res = -1; - if(setting instanceof MusicFolderSetting) { - titleView.setText(((MusicFolderSetting) setting).getLabel()); - } else { - // Last resort to display the raw value - titleView.setText(name); - } - - if(res != -1) { - titleView.setText(res); - } + protected void setObjectImpl(Setting setting, Boolean isEditable) { + // Can't edit non-role parts + String name = setting.getName(); + if(name.indexOf("Role") == -1 && !(setting instanceof MusicFolderSetting)) { + item2 = false; + } - if(setting.getValue()) { - checkBox.setChecked(setting.getValue()); - } else { - checkBox.setChecked(false); - } + int res = -1; + if(setting instanceof MusicFolderSetting) { + titleView.setText(((MusicFolderSetting) setting).getLabel()); + } else { + // Last resort to display the raw value + titleView.setText(name); + } - checkBox.setEnabled(item2); - } + if(res != -1) { + titleView.setText(res); + } - @Override - public boolean isCheckable() { - return item2; - } + if(setting.getValue()) { + checkBox.setChecked(setting.getValue()); + } else { + checkBox.setChecked(false); + } - public void setChecked(boolean checked) { - checkBox.setChecked(checked); - } + checkBox.setEnabled(item2); + } + + @Override + public boolean isCheckable() { + return item2; + } + + public void setChecked(boolean checked) { + checkBox.setChecked(checked); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/SongView.java b/app/src/main/java/net/nullsum/audinaut/view/SongView.java index a586531..3af6e2c 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/SongView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/SongView.java @@ -40,54 +40,54 @@ import java.io.File; * @author Sindre Mehus */ public class SongView extends UpdateView2 { - private static final String TAG = SongView.class.getSimpleName(); + private static final String TAG = SongView.class.getSimpleName(); - private TextView trackTextView; - private TextView titleTextView; - private TextView playingTextView; - private TextView artistTextView; - private TextView durationTextView; - private TextView statusTextView; - private ImageView statusImageView; - private ImageView playedButton; - private View bottomRowView; + private TextView trackTextView; + private TextView titleTextView; + private TextView playingTextView; + private TextView artistTextView; + private TextView durationTextView; + private TextView statusTextView; + private ImageView statusImageView; + private ImageView playedButton; + private View bottomRowView; - private DownloadService downloadService; - private long revision = -1; - private DownloadFile downloadFile; - private boolean dontChangeDownloadFile = false; + private DownloadService downloadService; + private long revision = -1; + private DownloadFile downloadFile; + private boolean dontChangeDownloadFile = false; - private boolean playing = false; - private boolean rightImage = false; - private int moreImage = 0; - private boolean isWorkDone = false; - private boolean isSaved = false; - private File partialFile; - private boolean partialFileExists = false; - private boolean loaded = false; - private boolean isPlayed = false; - private boolean isPlayedShown = false; - private boolean showAlbum = false; + private boolean playing = false; + private boolean rightImage = false; + private int moreImage = 0; + private boolean isWorkDone = false; + private boolean isSaved = false; + private File partialFile; + private boolean partialFileExists = false; + private boolean loaded = false; + private boolean isPlayed = false; + private boolean isPlayedShown = false; + private boolean showAlbum = false; - public SongView(Context context) { - super(context); - LayoutInflater.from(context).inflate(R.layout.song_list_item, this, true); + public SongView(Context context) { + super(context); + LayoutInflater.from(context).inflate(R.layout.song_list_item, this, true); - trackTextView = (TextView) findViewById(R.id.song_track); - titleTextView = (TextView) findViewById(R.id.song_title); - artistTextView = (TextView) findViewById(R.id.song_artist); - durationTextView = (TextView) findViewById(R.id.song_duration); - statusTextView = (TextView) findViewById(R.id.song_status); - statusImageView = (ImageView) findViewById(R.id.song_status_icon); - playedButton = (ImageButton) findViewById(R.id.song_played); - moreButton = (ImageView) findViewById(R.id.item_more); - bottomRowView = findViewById(R.id.song_bottom); - } + trackTextView = (TextView) findViewById(R.id.song_track); + titleTextView = (TextView) findViewById(R.id.song_title); + artistTextView = (TextView) findViewById(R.id.song_artist); + durationTextView = (TextView) findViewById(R.id.song_duration); + statusTextView = (TextView) findViewById(R.id.song_status); + statusImageView = (ImageView) findViewById(R.id.song_status_icon); + playedButton = (ImageButton) findViewById(R.id.song_played); + moreButton = (ImageView) findViewById(R.id.item_more); + bottomRowView = findViewById(R.id.song_bottom); + } - public void setObjectImpl(MusicDirectory.Entry song, Boolean checkable) { - this.checkable = checkable; + public void setObjectImpl(MusicDirectory.Entry song, Boolean checkable) { + this.checkable = checkable; - StringBuilder artist = new StringBuilder(40); + StringBuilder artist = new StringBuilder(40); if(showAlbum) { artist.append(song.getAlbum()); @@ -98,142 +98,142 @@ public class SongView extends UpdateView2 { durationTextView.setText(Util.formatDuration(song.getDuration())); bottomRowView.setVisibility(View.VISIBLE); - String title = song.getTitle(); - Integer track = song.getTrack(); - TextView newPlayingTextView; - if(track != null && Util.getDisplayTrack(context)) { - trackTextView.setText(String.format("%02d", track)); - trackTextView.setVisibility(View.VISIBLE); - newPlayingTextView = trackTextView; - } else { - trackTextView.setVisibility(View.GONE); - newPlayingTextView = titleTextView; - } + String title = song.getTitle(); + Integer track = song.getTrack(); + TextView newPlayingTextView; + if(track != null && Util.getDisplayTrack(context)) { + trackTextView.setText(String.format("%02d", track)); + trackTextView.setVisibility(View.VISIBLE); + newPlayingTextView = trackTextView; + } else { + trackTextView.setVisibility(View.GONE); + newPlayingTextView = titleTextView; + } - if(newPlayingTextView != playingTextView || playingTextView == null) { - if(playing) { - playingTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); - playing = false; - } + if(newPlayingTextView != playingTextView || playingTextView == null) { + if(playing) { + playingTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); + playing = false; + } - playingTextView = newPlayingTextView; - } + playingTextView = newPlayingTextView; + } - titleTextView.setText(title); - artistTextView.setText(artist); + titleTextView.setText(title); + artistTextView.setText(artist); - this.setBackgroundColor(0x00000000); + this.setBackgroundColor(0x00000000); - revision = -1; - loaded = false; - dontChangeDownloadFile = false; - } + revision = -1; + loaded = false; + dontChangeDownloadFile = false; + } - public void setDownloadFile(DownloadFile downloadFile) { - this.downloadFile = downloadFile; - dontChangeDownloadFile = true; - } + public void setDownloadFile(DownloadFile downloadFile) { + this.downloadFile = downloadFile; + dontChangeDownloadFile = true; + } - public DownloadFile getDownloadFile() { - return downloadFile; - } + public DownloadFile getDownloadFile() { + return downloadFile; + } - @Override - protected void updateBackground() { - if (downloadService == null) { - downloadService = DownloadService.getInstance(); - if(downloadService == null) { - return; - } - } + @Override + protected void updateBackground() { + if (downloadService == null) { + downloadService = DownloadService.getInstance(); + if(downloadService == null) { + return; + } + } - long newRevision = downloadService.getDownloadListUpdateRevision(); - if((revision != newRevision && dontChangeDownloadFile == false) || downloadFile == null) { - downloadFile = downloadService.forSong(item); - revision = newRevision; - } + long newRevision = downloadService.getDownloadListUpdateRevision(); + if((revision != newRevision && dontChangeDownloadFile == false) || downloadFile == null) { + downloadFile = downloadService.forSong(item); + revision = newRevision; + } - isWorkDone = downloadFile.isWorkDone(); - isSaved = downloadFile.isSaved(); - partialFile = downloadFile.getPartialFile(); - partialFileExists = partialFile.exists(); + isWorkDone = downloadFile.isWorkDone(); + isSaved = downloadFile.isSaved(); + partialFile = downloadFile.getPartialFile(); + partialFileExists = partialFile.exists(); - // Check if needs to load metadata: check against all fields that we know are null in offline mode - if(item.getBitRate() == null && item.getDuration() == null && item.getDiscNumber() == null && isWorkDone) { - item.loadMetadata(downloadFile.getCompleteFile()); - loaded = true; - } - } + // Check if needs to load metadata: check against all fields that we know are null in offline mode + if(item.getBitRate() == null && item.getDuration() == null && item.getDiscNumber() == null && isWorkDone) { + item.loadMetadata(downloadFile.getCompleteFile()); + loaded = true; + } + } - @Override - protected void update() { - if(loaded) { - setObjectImpl(item, item2); - } - if (downloadService == null || downloadFile == null) { - return; - } + @Override + protected void update() { + if(loaded) { + setObjectImpl(item, item2); + } + if (downloadService == null || downloadFile == null) { + return; + } - if (isWorkDone) { - int moreImage = isSaved ? R.drawable.download_pinned : R.drawable.download_cached; - if(moreImage != this.moreImage) { - moreButton.setImageResource(moreImage); - this.moreImage = moreImage; - } - } else if(this.moreImage != R.drawable.download_none_light) { - moreButton.setImageResource(DrawableTint.getDrawableRes(context, R.attr.download_none)); - this.moreImage = R.drawable.download_none_light; - } + if (isWorkDone) { + int moreImage = isSaved ? R.drawable.download_pinned : R.drawable.download_cached; + if(moreImage != this.moreImage) { + moreButton.setImageResource(moreImage); + this.moreImage = moreImage; + } + } else if(this.moreImage != R.drawable.download_none_light) { + moreButton.setImageResource(DrawableTint.getDrawableRes(context, R.attr.download_none)); + this.moreImage = R.drawable.download_none_light; + } - if (downloadFile.isDownloading() && !downloadFile.isDownloadCancelled() && partialFileExists) { - double percentage = (partialFile.length() * 100.0) / downloadFile.getEstimatedSize(); - percentage = Math.min(percentage, 100); - statusTextView.setText((int)percentage + " %"); - if(!rightImage) { - statusImageView.setVisibility(View.VISIBLE); - rightImage = true; - } - } else if(rightImage) { - statusTextView.setText(null); - statusImageView.setVisibility(View.GONE); - rightImage = false; - } + if (downloadFile.isDownloading() && !downloadFile.isDownloadCancelled() && partialFileExists) { + double percentage = (partialFile.length() * 100.0) / downloadFile.getEstimatedSize(); + percentage = Math.min(percentage, 100); + statusTextView.setText((int)percentage + " %"); + if(!rightImage) { + statusImageView.setVisibility(View.VISIBLE); + rightImage = true; + } + } else if(rightImage) { + statusTextView.setText(null); + statusImageView.setVisibility(View.GONE); + rightImage = false; + } - boolean playing = Util.equals(downloadService.getCurrentPlaying(), downloadFile); - if (playing) { - if(!this.playing) { - this.playing = playing; - playingTextView.setCompoundDrawablesWithIntrinsicBounds(DrawableTint.getDrawableRes(context, R.attr.playing), 0, 0, 0); - } - } else { - if(this.playing) { - this.playing = playing; - playingTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); - } - } + boolean playing = Util.equals(downloadService.getCurrentPlaying(), downloadFile); + if (playing) { + if(!this.playing) { + this.playing = playing; + playingTextView.setCompoundDrawablesWithIntrinsicBounds(DrawableTint.getDrawableRes(context, R.attr.playing), 0, 0, 0); + } + } else { + if(this.playing) { + this.playing = playing; + playingTextView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); + } + } - if(isPlayed) { - if(!isPlayedShown) { - if(playedButton.getDrawable() == null) { - playedButton.setImageDrawable(DrawableTint.getTintedDrawable(context, R.drawable.ic_toggle_played)); - } + if(isPlayed) { + if(!isPlayedShown) { + if(playedButton.getDrawable() == null) { + playedButton.setImageDrawable(DrawableTint.getTintedDrawable(context, R.drawable.ic_toggle_played)); + } - playedButton.setVisibility(View.VISIBLE); - isPlayedShown = true; - } - } else { - if(isPlayedShown) { - playedButton.setVisibility(View.GONE); - isPlayedShown = false; - } - } - } + playedButton.setVisibility(View.VISIBLE); + isPlayedShown = true; + } + } else { + if(isPlayedShown) { + playedButton.setVisibility(View.GONE); + isPlayedShown = false; + } + } + } - public MusicDirectory.Entry getEntry() { - return item; - } + public MusicDirectory.Entry getEntry() { + return item; + } - public void setShowAlbum(boolean showAlbum) { - this.showAlbum = showAlbum; - } + public void setShowAlbum(boolean showAlbum) { + this.showAlbum = showAlbum; + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/SquareImageView.java b/app/src/main/java/net/nullsum/audinaut/view/SquareImageView.java index 3d3b4d8..d7b7224 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/SquareImageView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/SquareImageView.java @@ -1,16 +1,16 @@ /* This file is part of Subsonic. - Subsonic 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. - Subsonic 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 Subsonic. If not, see . - Copyright 2014 (C) Scott Jackson + Subsonic 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. + Subsonic 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 Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson */ package net.nullsum.audinaut.view; @@ -20,13 +20,13 @@ import android.util.AttributeSet; import android.widget.ImageView; public class SquareImageView extends RecyclingImageView { - public SquareImageView(final Context context, final AttributeSet attrs) { - super(context, attrs); - } + public SquareImageView(final Context context, final AttributeSet attrs) { + super(context, attrs); + } - @Override - public void onMeasure(final int widthSpec, final int heightSpec) { - super.onMeasure(widthSpec, heightSpec); - setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); - } + @Override + public void onMeasure(final int widthSpec, final int heightSpec) { + super.onMeasure(widthSpec, heightSpec); + setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/UpdateView.java b/app/src/main/java/net/nullsum/audinaut/view/UpdateView.java index e496c63..dcd627a 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/UpdateView.java +++ b/app/src/main/java/net/nullsum/audinaut/view/UpdateView.java @@ -41,270 +41,270 @@ import net.nullsum.audinaut.util.DrawableTint; import net.nullsum.audinaut.util.SilentBackgroundTask; public abstract class UpdateView extends LinearLayout { - private static final String TAG = UpdateView.class.getSimpleName(); - private static final WeakHashMap INSTANCES = new WeakHashMap(); + private static final String TAG = UpdateView.class.getSimpleName(); + private static final WeakHashMap INSTANCES = new WeakHashMap(); - protected static Handler backgroundHandler; - protected static Handler uiHandler; - private static Runnable updateRunnable; - private static int activeActivities = 0; + protected static Handler backgroundHandler; + protected static Handler uiHandler; + private static Runnable updateRunnable; + private static int activeActivities = 0; - protected Context context; - protected T item; - protected ImageView moreButton; - protected View coverArtView; - - protected boolean exists = false; - protected boolean pinned = false; - protected boolean shaded = false; - protected SilentBackgroundTask imageTask = null; - protected Drawable startBackgroundDrawable; - - protected final boolean autoUpdate; - protected boolean checkable; - - public UpdateView(Context context) { - this(context, true); - } - public UpdateView(Context context, boolean autoUpdate) { - super(context); - this.context = context; - this.autoUpdate = autoUpdate; - - setLayoutParams(new AbsListView.LayoutParams( - ViewGroup.LayoutParams.FILL_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT)); - - if(autoUpdate) { - INSTANCES.put(this, null); - } - startUpdater(); - } - - @Override - public void setPressed(boolean pressed) { - - } - - public void setObject(T obj) { - if(item == obj) { - return; - } + protected Context context; + protected T item; + protected ImageView moreButton; + protected View coverArtView; - item = obj; - if(imageTask != null) { - imageTask.cancel(); - imageTask = null; - } - if(coverArtView != null && coverArtView instanceof ImageView) { - ((ImageView) coverArtView).setImageDrawable(null); - } - setObjectImpl(obj); - updateBackground(); - update(); - } - public void setObject(T obj1, Object obj2) { - setObject(obj1, null); - } - protected abstract void setObjectImpl(T obj); - - private static synchronized void startUpdater() { - if(uiHandler != null) { - return; - } - - uiHandler = new Handler(); - // Needed so handler is never null until thread creates it - backgroundHandler = uiHandler; - updateRunnable = new Runnable() { + protected boolean exists = false; + protected boolean pinned = false; + protected boolean shaded = false; + protected SilentBackgroundTask imageTask = null; + protected Drawable startBackgroundDrawable; + + protected final boolean autoUpdate; + protected boolean checkable; + + public UpdateView(Context context) { + this(context, true); + } + public UpdateView(Context context, boolean autoUpdate) { + super(context); + this.context = context; + this.autoUpdate = autoUpdate; + + setLayoutParams(new AbsListView.LayoutParams( + ViewGroup.LayoutParams.FILL_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + + if(autoUpdate) { + INSTANCES.put(this, null); + } + startUpdater(); + } + + @Override + public void setPressed(boolean pressed) { + + } + + public void setObject(T obj) { + if(item == obj) { + return; + } + + item = obj; + if(imageTask != null) { + imageTask.cancel(); + imageTask = null; + } + if(coverArtView != null && coverArtView instanceof ImageView) { + ((ImageView) coverArtView).setImageDrawable(null); + } + setObjectImpl(obj); + updateBackground(); + update(); + } + public void setObject(T obj1, Object obj2) { + setObject(obj1, null); + } + protected abstract void setObjectImpl(T obj); + + private static synchronized void startUpdater() { + if(uiHandler != null) { + return; + } + + uiHandler = new Handler(); + // Needed so handler is never null until thread creates it + backgroundHandler = uiHandler; + updateRunnable = new Runnable() { @Override public void run() { updateAll(); } }; - - new Thread(new Runnable() { - public void run() { - Looper.prepare(); - backgroundHandler = new Handler(Looper.myLooper()); - uiHandler.post(updateRunnable); - Looper.loop(); - } - }, "UpdateView").start(); + + new Thread(new Runnable() { + public void run() { + Looper.prepare(); + backgroundHandler = new Handler(Looper.myLooper()); + uiHandler.post(updateRunnable); + Looper.loop(); + } + }, "UpdateView").start(); } - public static synchronized void triggerUpdate() { - if(backgroundHandler != null) { - uiHandler.removeCallbacksAndMessages(null); - backgroundHandler.removeCallbacksAndMessages(null); - uiHandler.post(updateRunnable); - } - } + public static synchronized void triggerUpdate() { + if(backgroundHandler != null) { + uiHandler.removeCallbacksAndMessages(null); + backgroundHandler.removeCallbacksAndMessages(null); + uiHandler.post(updateRunnable); + } + } private static void updateAll() { try { - // If nothing can see this, stop updating - if(activeActivities == 0) { - activeActivities--; - return; - } + // If nothing can see this, stop updating + if(activeActivities == 0) { + activeActivities--; + return; + } - List views = new ArrayList(); + List views = new ArrayList(); for (UpdateView view : INSTANCES.keySet()) { if (view.isShown()) { - views.add(view); + views.add(view); } } - if(views.size() > 0) { - updateAllLive(views); - } else { - uiHandler.postDelayed(updateRunnable, 2000L); - } + if(views.size() > 0) { + updateAllLive(views); + } else { + uiHandler.postDelayed(updateRunnable, 2000L); + } } catch (Throwable x) { Log.w(TAG, "Error when updating song views.", x); } } - private static void updateAllLive(final List views) { - final Runnable runnable = new Runnable() { - @Override + private static void updateAllLive(final List views) { + final Runnable runnable = new Runnable() { + @Override public void run() { - try { - for(UpdateView view: views) { - view.update(); - } - } catch (Throwable x) { - Log.w(TAG, "Error when updating song views.", x); - } - uiHandler.postDelayed(updateRunnable, 1000L); - } - }; - - backgroundHandler.post(new Runnable() { - @Override + try { + for(UpdateView view: views) { + view.update(); + } + } catch (Throwable x) { + Log.w(TAG, "Error when updating song views.", x); + } + uiHandler.postDelayed(updateRunnable, 1000L); + } + }; + + backgroundHandler.post(new Runnable() { + @Override public void run() { - try { - for(UpdateView view: views) { - view.updateBackground(); - } - uiHandler.post(runnable); - } catch (Throwable x) { - Log.w(TAG, "Error when updating song views.", x); - } - } - }); - } + try { + for(UpdateView view: views) { + view.updateBackground(); + } + uiHandler.post(runnable); + } catch (Throwable x) { + Log.w(TAG, "Error when updating song views.", x); + } + } + }); + } - public static boolean hasActiveActivity() { - return activeActivities > 0; - } + public static boolean hasActiveActivity() { + return activeActivities > 0; + } - public static void addActiveActivity() { - activeActivities++; + public static void addActiveActivity() { + activeActivities++; - if(activeActivities == 0 && uiHandler != null && updateRunnable != null) { - activeActivities++; - uiHandler.post(updateRunnable); - } - } - public static void removeActiveActivity() { - activeActivities--; - } + if(activeActivities == 0 && uiHandler != null && updateRunnable != null) { + activeActivities++; + uiHandler.post(updateRunnable); + } + } + public static void removeActiveActivity() { + activeActivities--; + } - public static MusicDirectory.Entry findEntry(MusicDirectory.Entry entry) { - for(UpdateView view: INSTANCES.keySet()) { - MusicDirectory.Entry check = null; - if(view instanceof SongView) { - check = ((SongView) view).getEntry(); - } else if(view instanceof AlbumView) { - check = ((AlbumView) view).getEntry(); - } + public static MusicDirectory.Entry findEntry(MusicDirectory.Entry entry) { + for(UpdateView view: INSTANCES.keySet()) { + MusicDirectory.Entry check = null; + if(view instanceof SongView) { + check = ((SongView) view).getEntry(); + } else if(view instanceof AlbumView) { + check = ((AlbumView) view).getEntry(); + } - if(check != null && entry != check && check.getId().equals(entry.getId())) { - return check; - } - } + if(check != null && entry != check && check.getId().equals(entry.getId())) { + return check; + } + } - return null; - } - - protected void updateBackground() { - - } - protected void update() { - if(moreButton != null) { - if(exists || pinned) { - if(!shaded) { - moreButton.setImageResource(exists ? R.drawable.download_cached : R.drawable.download_pinned); - shaded = true; - } - } else { - if(shaded) { - moreButton.setImageResource(DrawableTint.getDrawableRes(context, R.attr.download_none)); - shaded = false; - } - } - } - - if(coverArtView != null && coverArtView instanceof RecyclingImageView) { - RecyclingImageView recyclingImageView = (RecyclingImageView) coverArtView; - if(recyclingImageView.isInvalidated()) { - onUpdateImageView(); - } - } - } + return null; + } - public boolean isCheckable() { - return checkable; - } - public void setChecked(boolean checked) { - View child = getChildAt(0); - if (checked && startBackgroundDrawable == null) { - startBackgroundDrawable = child.getBackground(); - child.setBackgroundColor(DrawableTint.getColorRes(context, R.attr.colorPrimary)); - } else if (!checked && startBackgroundDrawable != null) { - child.setBackgroundDrawable(startBackgroundDrawable); - startBackgroundDrawable = null; - } - } + protected void updateBackground() { - public void onClick() { + } + protected void update() { + if(moreButton != null) { + if(exists || pinned) { + if(!shaded) { + moreButton.setImageResource(exists ? R.drawable.download_cached : R.drawable.download_pinned); + shaded = true; + } + } else { + if(shaded) { + moreButton.setImageResource(DrawableTint.getDrawableRes(context, R.attr.download_none)); + shaded = false; + } + } + } - } + if(coverArtView != null && coverArtView instanceof RecyclingImageView) { + RecyclingImageView recyclingImageView = (RecyclingImageView) coverArtView; + if(recyclingImageView.isInvalidated()) { + onUpdateImageView(); + } + } + } - public void onUpdateImageView() { + public boolean isCheckable() { + return checkable; + } + public void setChecked(boolean checked) { + View child = getChildAt(0); + if (checked && startBackgroundDrawable == null) { + startBackgroundDrawable = child.getBackground(); + child.setBackgroundColor(DrawableTint.getColorRes(context, R.attr.colorPrimary)); + } else if (!checked && startBackgroundDrawable != null) { + child.setBackgroundDrawable(startBackgroundDrawable); + startBackgroundDrawable = null; + } + } - } + public void onClick() { - public static class UpdateViewHolder extends RecyclerView.ViewHolder { - private UpdateView updateView; - private View view; - private T item; + } - public UpdateViewHolder(UpdateView itemView) { - super(itemView); + public void onUpdateImageView() { - this.updateView = itemView; - this.view = itemView; - } + } - // Different is so that call is not ambiguous - public UpdateViewHolder(View view, boolean different) { - super(view); - this.view = view; - } + public static class UpdateViewHolder extends RecyclerView.ViewHolder { + private UpdateView updateView; + private View view; + private T item; - public UpdateView getUpdateView() { - return updateView; - } - public View getView() { - return view; - } - public void setItem(T item) { - this.item = item; - } - public T getItem() { - return item; - } - } + public UpdateViewHolder(UpdateView itemView) { + super(itemView); + + this.updateView = itemView; + this.view = itemView; + } + + // Different is so that call is not ambiguous + public UpdateViewHolder(View view, boolean different) { + super(view); + this.view = view; + } + + public UpdateView getUpdateView() { + return updateView; + } + public View getView() { + return view; + } + public void setItem(T item) { + this.item = item; + } + public T getItem() { + return item; + } + } } diff --git a/app/src/main/java/net/nullsum/audinaut/view/UpdateView2.java b/app/src/main/java/net/nullsum/audinaut/view/UpdateView2.java index 6ce688c..5069657 100644 --- a/app/src/main/java/net/nullsum/audinaut/view/UpdateView2.java +++ b/app/src/main/java/net/nullsum/audinaut/view/UpdateView2.java @@ -4,52 +4,52 @@ import android.content.Context; import android.widget.ImageView; public abstract class UpdateView2 extends UpdateView { - protected T2 item2; + protected T2 item2; - public UpdateView2(Context context) { - super(context); - } + public UpdateView2(Context context) { + super(context); + } - public UpdateView2(Context context, boolean autoUpdate) { - super(context, autoUpdate); - } + public UpdateView2(Context context, boolean autoUpdate) { + super(context, autoUpdate); + } - public final void setObject(T1 obj1) { - setObject(obj1, null); - } - @Override - public void setObject(T1 obj1, Object obj2) { - if(item == obj1 && item2 == obj2) { - return; - } + public final void setObject(T1 obj1) { + setObject(obj1, null); + } + @Override + public void setObject(T1 obj1, Object obj2) { + if(item == obj1 && item2 == obj2) { + return; + } - item = obj1; - item2 = (T2) obj2; - if(imageTask != null) { - imageTask.cancel(); - imageTask = null; - } - if(coverArtView != null && coverArtView instanceof ImageView) { - ((ImageView) coverArtView).setImageDrawable(null); - } + item = obj1; + item2 = (T2) obj2; + if(imageTask != null) { + imageTask.cancel(); + imageTask = null; + } + if(coverArtView != null && coverArtView instanceof ImageView) { + ((ImageView) coverArtView).setImageDrawable(null); + } - setObjectImpl(item, item2); - backgroundHandler.post(new Runnable() { - @Override - public void run() { - updateBackground(); - uiHandler.post(new Runnable() { - @Override - public void run() { - update(); - } - }); - } - }); - } + setObjectImpl(item, item2); + backgroundHandler.post(new Runnable() { + @Override + public void run() { + updateBackground(); + uiHandler.post(new Runnable() { + @Override + public void run() { + update(); + } + }); + } + }); + } - protected final void setObjectImpl(T1 obj1) { - setObjectImpl(obj1, null); - } - protected abstract void setObjectImpl(T1 obj1, T2 obj2); + protected final void setObjectImpl(T1 obj1) { + setObjectImpl(obj1, null); + } + protected abstract void setObjectImpl(T1 obj1, T2 obj2); } diff --git a/app/src/main/res/anim/enter_from_left.xml b/app/src/main/res/anim/enter_from_left.xml index 3c11332..b5de863 100644 --- a/app/src/main/res/anim/enter_from_left.xml +++ b/app/src/main/res/anim/enter_from_left.xml @@ -1,12 +1,12 @@ + android:shareInterpolator="false"> - + - - \ No newline at end of file + + diff --git a/app/src/main/res/anim/enter_from_right.xml b/app/src/main/res/anim/enter_from_right.xml index 568a0c0..e6d03d2 100644 --- a/app/src/main/res/anim/enter_from_right.xml +++ b/app/src/main/res/anim/enter_from_right.xml @@ -1,12 +1,12 @@ + android:shareInterpolator="false"> - + - - \ No newline at end of file + + diff --git a/app/src/main/res/anim/exit_to_left.xml b/app/src/main/res/anim/exit_to_left.xml index 2cb8feb..a2314cf 100644 --- a/app/src/main/res/anim/exit_to_left.xml +++ b/app/src/main/res/anim/exit_to_left.xml @@ -1,12 +1,12 @@ + android:shareInterpolator="false"> - + - - \ No newline at end of file + + diff --git a/app/src/main/res/anim/exit_to_right.xml b/app/src/main/res/anim/exit_to_right.xml index a3fa5ba..0d501cc 100644 --- a/app/src/main/res/anim/exit_to_right.xml +++ b/app/src/main/res/anim/exit_to_right.xml @@ -1,12 +1,12 @@ + android:shareInterpolator="false"> - + - - \ No newline at end of file + + diff --git a/app/src/main/res/anim/fade_in.xml b/app/src/main/res/anim/fade_in.xml index c41db06..b6a2997 100644 --- a/app/src/main/res/anim/fade_in.xml +++ b/app/src/main/res/anim/fade_in.xml @@ -1,5 +1,5 @@ \ No newline at end of file + android:duration="500" + android:fromAlpha="0.0" + android:toAlpha="1.0" /> diff --git a/app/src/main/res/anim/fade_out.xml b/app/src/main/res/anim/fade_out.xml index d615f2a..14a58c1 100644 --- a/app/src/main/res/anim/fade_out.xml +++ b/app/src/main/res/anim/fade_out.xml @@ -1,5 +1,5 @@ \ No newline at end of file + android:duration="500" + android:fromAlpha="1.0" + android:toAlpha="0.0" /> diff --git a/app/src/main/res/anim/push_down_in.xml b/app/src/main/res/anim/push_down_in.xml index 6ab9a04..6cfbd1b 100644 --- a/app/src/main/res/anim/push_down_in.xml +++ b/app/src/main/res/anim/push_down_in.xml @@ -4,9 +4,9 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,8 +15,8 @@ --> - - diff --git a/app/src/main/res/anim/push_down_out.xml b/app/src/main/res/anim/push_down_out.xml index ce36458..3d0b8af 100644 --- a/app/src/main/res/anim/push_down_out.xml +++ b/app/src/main/res/anim/push_down_out.xml @@ -4,9 +4,9 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,8 +15,8 @@ --> - - diff --git a/app/src/main/res/anim/push_up_in.xml b/app/src/main/res/anim/push_up_in.xml index 6ef582c..6a0ba14 100644 --- a/app/src/main/res/anim/push_up_in.xml +++ b/app/src/main/res/anim/push_up_in.xml @@ -4,9 +4,9 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,8 +15,8 @@ --> - - diff --git a/app/src/main/res/anim/push_up_out.xml b/app/src/main/res/anim/push_up_out.xml index 2b267d5..c0a1e87 100644 --- a/app/src/main/res/anim/push_up_out.xml +++ b/app/src/main/res/anim/push_up_out.xml @@ -4,9 +4,9 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -15,8 +15,8 @@ --> - - diff --git a/app/src/main/res/drawable-v21/notification_backward.xml b/app/src/main/res/drawable-v21/notification_backward.xml index ffebb00..2130e0e 100644 --- a/app/src/main/res/drawable-v21/notification_backward.xml +++ b/app/src/main/res/drawable-v21/notification_backward.xml @@ -1,4 +1,4 @@ \ No newline at end of file + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/media_backward_light"/> diff --git a/app/src/main/res/drawable-v21/notification_close.xml b/app/src/main/res/drawable-v21/notification_close.xml index 4a93427..2b010b3 100644 --- a/app/src/main/res/drawable-v21/notification_close.xml +++ b/app/src/main/res/drawable-v21/notification_close.xml @@ -1,4 +1,4 @@ \ No newline at end of file + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/notification_close_light"/> diff --git a/app/src/main/res/drawable-v21/notification_forward.xml b/app/src/main/res/drawable-v21/notification_forward.xml index 0d3c93d..972cb2b 100644 --- a/app/src/main/res/drawable-v21/notification_forward.xml +++ b/app/src/main/res/drawable-v21/notification_forward.xml @@ -1,4 +1,4 @@ \ No newline at end of file + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/media_forward_light"/> diff --git a/app/src/main/res/drawable-v21/notification_pause.xml b/app/src/main/res/drawable-v21/notification_pause.xml index 330260f..dad7c7e 100644 --- a/app/src/main/res/drawable-v21/notification_pause.xml +++ b/app/src/main/res/drawable-v21/notification_pause.xml @@ -1,4 +1,4 @@ \ No newline at end of file + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/media_pause_light"/> diff --git a/app/src/main/res/drawable-v21/notification_start.xml b/app/src/main/res/drawable-v21/notification_start.xml index 75e23c0..f410eed 100644 --- a/app/src/main/res/drawable-v21/notification_start.xml +++ b/app/src/main/res/drawable-v21/notification_start.xml @@ -1,4 +1,4 @@ \ No newline at end of file + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/media_start_light"/> diff --git a/app/src/main/res/drawable/card_rounded_corners_black.xml b/app/src/main/res/drawable/card_rounded_corners_black.xml index 7592de6..8d977a6 100644 --- a/app/src/main/res/drawable/card_rounded_corners_black.xml +++ b/app/src/main/res/drawable/card_rounded_corners_black.xml @@ -1,6 +1,6 @@ - - - - \ No newline at end of file + + + + diff --git a/app/src/main/res/drawable/card_rounded_corners_dark.xml b/app/src/main/res/drawable/card_rounded_corners_dark.xml index 4db7d4b..2be3de9 100644 --- a/app/src/main/res/drawable/card_rounded_corners_dark.xml +++ b/app/src/main/res/drawable/card_rounded_corners_dark.xml @@ -1,6 +1,6 @@ - - - - \ No newline at end of file + + + + diff --git a/app/src/main/res/drawable/card_rounded_corners_light.xml b/app/src/main/res/drawable/card_rounded_corners_light.xml index 5475c3d..9b63f8e 100644 --- a/app/src/main/res/drawable/card_rounded_corners_light.xml +++ b/app/src/main/res/drawable/card_rounded_corners_light.xml @@ -1,6 +1,6 @@ - - - - \ No newline at end of file + + + + diff --git a/app/src/main/res/drawable/fast_scroller_bubble.xml b/app/src/main/res/drawable/fast_scroller_bubble.xml index 02dfee5..4f60829 100644 --- a/app/src/main/res/drawable/fast_scroller_bubble.xml +++ b/app/src/main/res/drawable/fast_scroller_bubble.xml @@ -1,16 +1,16 @@ + android:shape="rectangle"> - + - + - - \ No newline at end of file + + diff --git a/app/src/main/res/drawable/fast_scroller_handle.xml b/app/src/main/res/drawable/fast_scroller_handle.xml index e1744ce..550590d 100644 --- a/app/src/main/res/drawable/fast_scroller_handle.xml +++ b/app/src/main/res/drawable/fast_scroller_handle.xml @@ -1,26 +1,26 @@ - - - + + + - + - - - + + + - - - + + + - + - - - - \ No newline at end of file + + + + diff --git a/app/src/main/res/drawable/notification_backward.xml b/app/src/main/res/drawable/notification_backward.xml index f5fd965..bc4db5f 100644 --- a/app/src/main/res/drawable/notification_backward.xml +++ b/app/src/main/res/drawable/notification_backward.xml @@ -1,4 +1,4 @@ \ No newline at end of file + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/media_backward_dark"/> diff --git a/app/src/main/res/drawable/notification_close.xml b/app/src/main/res/drawable/notification_close.xml index 67a5696..9d356f5 100644 --- a/app/src/main/res/drawable/notification_close.xml +++ b/app/src/main/res/drawable/notification_close.xml @@ -1,4 +1,4 @@ \ No newline at end of file + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/notification_close_dark"/> diff --git a/app/src/main/res/drawable/notification_divider.xml b/app/src/main/res/drawable/notification_divider.xml index 95d50aa..b991115 100644 --- a/app/src/main/res/drawable/notification_divider.xml +++ b/app/src/main/res/drawable/notification_divider.xml @@ -1,5 +1,5 @@ - - - \ No newline at end of file + + + diff --git a/app/src/main/res/drawable/notification_forward.xml b/app/src/main/res/drawable/notification_forward.xml index 5dd1000..8095c4f 100644 --- a/app/src/main/res/drawable/notification_forward.xml +++ b/app/src/main/res/drawable/notification_forward.xml @@ -1,4 +1,4 @@ \ No newline at end of file + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/media_forward_dark"/> diff --git a/app/src/main/res/drawable/notification_pause.xml b/app/src/main/res/drawable/notification_pause.xml index c71a997..8c74aa6 100644 --- a/app/src/main/res/drawable/notification_pause.xml +++ b/app/src/main/res/drawable/notification_pause.xml @@ -1,4 +1,4 @@ \ No newline at end of file + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/media_pause_dark"/> diff --git a/app/src/main/res/drawable/notification_start.xml b/app/src/main/res/drawable/notification_start.xml index b31b4f8..d945bb9 100644 --- a/app/src/main/res/drawable/notification_start.xml +++ b/app/src/main/res/drawable/notification_start.xml @@ -1,4 +1,4 @@ \ No newline at end of file + xmlns:android="http://schemas.android.com/apk/res/android" + android:src="@drawable/media_start_dark"/> diff --git a/app/src/main/res/layout-land/download.xml b/app/src/main/res/layout-land/download.xml index 3e88d71..f53cc49 100644 --- a/app/src/main/res/layout-land/download.xml +++ b/app/src/main/res/layout-land/download.xml @@ -1,97 +1,97 @@ + android:id="@+id/download_layout" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="match_parent"> - + - + - + - + - + - + - - - + + + - + - + - + - - + + - + - - + + - + diff --git a/app/src/main/res/layout-large-land/abstract_fragment_container.xml b/app/src/main/res/layout-large-land/abstract_fragment_container.xml index 3901710..6a7aaba 100644 --- a/app/src/main/res/layout-large-land/abstract_fragment_container.xml +++ b/app/src/main/res/layout-large-land/abstract_fragment_container.xml @@ -1,21 +1,21 @@ + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginTop="?attr/actionBarSize"> - + - + - \ No newline at end of file + diff --git a/app/src/main/res/layout-large-land/download.xml b/app/src/main/res/layout-large-land/download.xml index bfbc585..6b781b6 100644 --- a/app/src/main/res/layout-large-land/download.xml +++ b/app/src/main/res/layout-large-land/download.xml @@ -1,96 +1,96 @@ + android:id="@+id/download_layout" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="match_parent"> - + - + - + - + - - - + + + - + - + - + - + - + - - + + - + - - - + + + diff --git a/app/src/main/res/layout-port/download.xml b/app/src/main/res/layout-port/download.xml index d9c1033..632ed80 100644 --- a/app/src/main/res/layout-port/download.xml +++ b/app/src/main/res/layout-port/download.xml @@ -1,89 +1,89 @@ + android:id="@+id/download_layout_container" + android:layout_width="match_parent" + android:layout_height="match_parent"> - + - + - + - + - + - + - - - - + + + + - + - - + + - + - + - + - - + + diff --git a/app/src/main/res/layout/abstract_activity.xml b/app/src/main/res/layout/abstract_activity.xml index 56db143..dc5ba64 100644 --- a/app/src/main/res/layout/abstract_activity.xml +++ b/app/src/main/res/layout/abstract_activity.xml @@ -1,22 +1,22 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/drawer_layout" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:fitsSystemWindows="true"> - - + + - - + + diff --git a/app/src/main/res/layout/abstract_fragment_activity.xml b/app/src/main/res/layout/abstract_fragment_activity.xml index 9e18b95..13cd632 100644 --- a/app/src/main/res/layout/abstract_fragment_activity.xml +++ b/app/src/main/res/layout/abstract_fragment_activity.xml @@ -1,147 +1,147 @@ + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:sothree="http://schemas.android.com/apk/res-auto" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:id="@+id/slide_up_panel" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="bottom" + sothree:umanoPanelHeight="?attr/actionBarSize" + sothree:umanoShadowHeight="4dp" + sothree:umanoDragView="@+id/slide_up_swipe_target"> - + - + - - + + - + - + - + - + - + - + - + - - + + - - + + - + - + - + - + - + - - - - + + + + - - + + diff --git a/app/src/main/res/layout/abstract_fragment_container.xml b/app/src/main/res/layout/abstract_fragment_container.xml index f13356c..6d19b2b 100644 --- a/app/src/main/res/layout/abstract_fragment_container.xml +++ b/app/src/main/res/layout/abstract_fragment_container.xml @@ -1,6 +1,6 @@ \ No newline at end of file + android:id="@+id/fragment_container" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_marginTop="?attr/actionBarSize"/> diff --git a/app/src/main/res/layout/abstract_recycler_fragment.xml b/app/src/main/res/layout/abstract_recycler_fragment.xml index 81502b0..609e093 100644 --- a/app/src/main/res/layout/abstract_recycler_fragment.xml +++ b/app/src/main/res/layout/abstract_recycler_fragment.xml @@ -1,36 +1,36 @@ + android:id="@+id/refresh_layout" + android:layout_width="fill_parent" + android:layout_height="fill_parent"> - + - + - + - - + + - - - \ No newline at end of file + + + diff --git a/app/src/main/res/layout/actionbar_spinner.xml b/app/src/main/res/layout/actionbar_spinner.xml index f719a67..19c5ead 100644 --- a/app/src/main/res/layout/actionbar_spinner.xml +++ b/app/src/main/res/layout/actionbar_spinner.xml @@ -1,8 +1,8 @@ \ No newline at end of file + android:id="@+id/spinner" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:prompt="@string/common.appname" + style="?attr/android:spinnerItemStyle" + android:overlapAnchor="false"/> diff --git a/app/src/main/res/layout/album_cell_item.xml b/app/src/main/res/layout/album_cell_item.xml index efcfb30..b2f341f 100644 --- a/app/src/main/res/layout/album_cell_item.xml +++ b/app/src/main/res/layout/album_cell_item.xml @@ -1,77 +1,77 @@ + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_margin="2dp"> - + - + - - + + - + - + - + - + - - - + + + - - + + - + diff --git a/app/src/main/res/layout/album_list_header.xml b/app/src/main/res/layout/album_list_header.xml index e78d0ac..7d8c873 100644 --- a/app/src/main/res/layout/album_list_header.xml +++ b/app/src/main/res/layout/album_list_header.xml @@ -1,29 +1,29 @@ + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> - + - - \ No newline at end of file + + diff --git a/app/src/main/res/layout/album_list_item.xml b/app/src/main/res/layout/album_list_item.xml index 3045d39..dada80b 100644 --- a/app/src/main/res/layout/album_list_item.xml +++ b/app/src/main/res/layout/album_list_item.xml @@ -1,56 +1,56 @@ + android:id="@id/drag_handle" + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground"> - + - - + + - + - + - + - + - + diff --git a/app/src/main/res/layout/appwidget4x1.xml b/app/src/main/res/layout/appwidget4x1.xml index 6fbf19f..34afe62 100644 --- a/app/src/main/res/layout/appwidget4x1.xml +++ b/app/src/main/res/layout/appwidget4x1.xml @@ -6,7 +6,7 @@ android:minHeight="40dp" android:background="@drawable/appwidget_bg" android:orientation="horizontal" - android:id="@+id/widget_root"> + android:id="@+id/widget_root"> + style="@style/NotificationButton"> + android:focusable="true" + android:focusableInTouchMode="true" + android:scrollHorizontally="true" + android:marqueeRepeatLimit="marquee_forever"> - - + + + style="@style/NotificationButton" /> + style="@style/NotificationButton" /> diff --git a/app/src/main/res/layout/appwidget4x2.xml b/app/src/main/res/layout/appwidget4x2.xml index 2493eb9..c6788e0 100644 --- a/app/src/main/res/layout/appwidget4x2.xml +++ b/app/src/main/res/layout/appwidget4x2.xml @@ -6,7 +6,7 @@ android:minHeight="110dp" android:background="@drawable/appwidget_bg" android:orientation="horizontal" - android:id="@+id/widget_root"> + android:id="@+id/widget_root"> + style="@style/NotificationButton"> + android:textStyle="bold" + android:focusable="true" + android:focusableInTouchMode="true" + android:scrollHorizontally="true" + android:marqueeRepeatLimit="marquee_forever"> - - + + - + + style="@style/NotificationButton" /> + style="@style/NotificationButton" /> diff --git a/app/src/main/res/layout/appwidget4x3.xml b/app/src/main/res/layout/appwidget4x3.xml index 5b2fa8c..4762d75 100644 --- a/app/src/main/res/layout/appwidget4x3.xml +++ b/app/src/main/res/layout/appwidget4x3.xml @@ -4,14 +4,14 @@ android:layout_height="fill_parent" android:background="@drawable/appwidget_bg" android:orientation="vertical" - android:id="@+id/widget_root"> + android:id="@+id/widget_root"> + style="@style/NotificationButton"> @@ -103,7 +103,7 @@ android:layout_height="56dip" android:layout_weight="1" android:src="@drawable/media_start_dark" - style="@style/NotificationButton" /> + style="@style/NotificationButton" /> + style="@style/NotificationButton" /> diff --git a/app/src/main/res/layout/appwidget4x4.xml b/app/src/main/res/layout/appwidget4x4.xml index 5c8bf1e..e6d4db0 100644 --- a/app/src/main/res/layout/appwidget4x4.xml +++ b/app/src/main/res/layout/appwidget4x4.xml @@ -4,14 +4,14 @@ android:layout_height="fill_parent" android:orientation="vertical" android:background="@drawable/appwidget_bg" - android:id="@+id/widget_root"> + android:id="@+id/widget_root"> + style="@style/NotificationButton"> + android:gravity="center" + android:textStyle="bold" + android:focusable="true" + android:focusableInTouchMode="true" + android:scrollHorizontally="true" + android:marqueeRepeatLimit="marquee_forever"> - - + + @@ -105,7 +105,7 @@ android:layout_height="56dip" android:layout_weight="1" android:src="@drawable/media_start_dark" - style="@style/NotificationButton" /> + style="@style/NotificationButton" /> + style="@style/NotificationButton" /> diff --git a/app/src/main/res/layout/basic_art_item.xml b/app/src/main/res/layout/basic_art_item.xml index 62eb6c3..354b975 100644 --- a/app/src/main/res/layout/basic_art_item.xml +++ b/app/src/main/res/layout/basic_art_item.xml @@ -1,34 +1,34 @@ + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground"> - + - + - + diff --git a/app/src/main/res/layout/basic_cell_item.xml b/app/src/main/res/layout/basic_cell_item.xml index a71a534..49b951a 100644 --- a/app/src/main/res/layout/basic_cell_item.xml +++ b/app/src/main/res/layout/basic_cell_item.xml @@ -1,45 +1,45 @@ + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_margin="2dp"> - + - + - + - + - - - + + + diff --git a/app/src/main/res/layout/basic_choice_item.xml b/app/src/main/res/layout/basic_choice_item.xml index e2dc220..3c0e766 100644 --- a/app/src/main/res/layout/basic_choice_item.xml +++ b/app/src/main/res/layout/basic_choice_item.xml @@ -1,27 +1,27 @@ + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground"> - + - - \ No newline at end of file + + diff --git a/app/src/main/res/layout/basic_count_item.xml b/app/src/main/res/layout/basic_count_item.xml index a8400a6..934cff8 100644 --- a/app/src/main/res/layout/basic_count_item.xml +++ b/app/src/main/res/layout/basic_count_item.xml @@ -1,37 +1,37 @@ + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground" + android:minHeight="50dip"> - + - + diff --git a/app/src/main/res/layout/basic_header.xml b/app/src/main/res/layout/basic_header.xml index b1f94b3..8ee53df 100644 --- a/app/src/main/res/layout/basic_header.xml +++ b/app/src/main/res/layout/basic_header.xml @@ -1,13 +1,13 @@ \ No newline at end of file + android:id="@+id/item_name" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceMedium" + android:background="@android:color/transparent" + android:textColor="?attr/colorAccent" + android:textStyle="bold" + android:paddingLeft="6dp" + android:paddingRight="6dp" + android:paddingTop="8dp" + android:paddingBottom="8dp"/> diff --git a/app/src/main/res/layout/basic_list_item.xml b/app/src/main/res/layout/basic_list_item.xml index 1e7db68..98e123b 100644 --- a/app/src/main/res/layout/basic_list_item.xml +++ b/app/src/main/res/layout/basic_list_item.xml @@ -1,28 +1,28 @@ + android:orientation="horizontal" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:background="?attr/selectableItemBackground"> - + - + diff --git a/app/src/main/res/layout/cache_location_buttons.xml b/app/src/main/res/layout/cache_location_buttons.xml index 31e1264..b77108e 100644 --- a/app/src/main/res/layout/cache_location_buttons.xml +++ b/app/src/main/res/layout/cache_location_buttons.xml @@ -1,19 +1,19 @@ + android:orientation="horizontal" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center"> -