diff --git a/app/src/main/java/it/anyplace/syncbrowser/LibraryHandler.java b/app/src/main/java/it/anyplace/syncbrowser/LibraryHandler.java index e753af5..7b57802 100644 --- a/app/src/main/java/it/anyplace/syncbrowser/LibraryHandler.java +++ b/app/src/main/java/it/anyplace/syncbrowser/LibraryHandler.java @@ -32,8 +32,7 @@ public class LibraryHandler { private SyncthingClient mSyncthingClient; private FolderBrowser mFolderBrowser; - public void init(Context context, OnIndexUpdatedListener onIndexUpdatedListener) { - mOnIndexUpdatedListener = onIndexUpdatedListener; + public void init(Context context) { mConfiguration = ConfigurationService.newLoader() .setCache(new File(context.getExternalCacheDir(), "cache")) .setDatabase(new File(context.getExternalFilesDir(null), "database")) @@ -50,6 +49,12 @@ public class LibraryHandler { Log.i(TAG, "loaded mConfiguration = " + mConfiguration.newWriter().dumpToString()); Log.i(TAG, "storage space = " + mConfiguration.getStorageInfo().dumpAvailableSpace()); mSyncthingClient = new it.anyplace.sync.client.SyncthingClient(mConfiguration); + //TODO listen for device events, update device list + mFolderBrowser = mSyncthingClient.getIndexHandler().newFolderBrowser(); + } + + public void setOnIndexUpdatedListener(OnIndexUpdatedListener onIndexUpdatedListener) { + mOnIndexUpdatedListener = onIndexUpdatedListener; mSyncthingClient.getIndexHandler().getEventBus().register(new Object() { @Subscribe @@ -69,8 +74,6 @@ public class LibraryHandler { mOnIndexUpdatedListener.onIndexUpdateComplete(); } }); - //TODO listen for device events, update device list - mFolderBrowser = mSyncthingClient.getIndexHandler().newFolderBrowser(); } public void destroy() { diff --git a/app/src/main/java/it/anyplace/syncbrowser/MainActivity.java b/app/src/main/java/it/anyplace/syncbrowser/MainActivity.java index e7abcd8..189b71d 100644 --- a/app/src/main/java/it/anyplace/syncbrowser/MainActivity.java +++ b/app/src/main/java/it/anyplace/syncbrowser/MainActivity.java @@ -27,7 +27,6 @@ import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v4.widget.DrawerLayout; -import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.Gravity; import android.view.View; @@ -74,12 +73,11 @@ import static com.google.common.base.Objects.equal; import static com.google.common.base.Preconditions.checkArgument; import static org.apache.commons.lang3.StringUtils.isBlank; -public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback { +public class MainActivity extends SyncbrowserActivity implements ActivityCompat.OnRequestPermissionsResultCallback { private static final String TAG = "MainActivity"; private static final int REQUEST_WRITE_STORAGE = 142; - private LibraryHandler mLibraryHandler; private AlertDialog mLoadingDialog; private MainContainerBinding mBinding; @@ -89,8 +87,6 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On mBinding = DataBindingUtil.setContentView(this, R.layout.main_container); - mLibraryHandler = new LibraryHandler(); - mBinding.mainContent.mainFolderAndFilesListView.setEmptyView(mBinding.mainContent.mainListViewEmptyElement); checkPermissions(); @@ -134,54 +130,6 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On } } }); - - new AsyncTask() { - - @Override - protected void onPreExecute() { - showLoadingDialog("loading config, starting syncthing client"); - } - - @Override - protected Void doInBackground(Void... voidd) { - mLibraryHandler.init(MainActivity.this, new LibraryHandler.OnIndexUpdatedListener() { - @Override - public void onIndexUpdateProgress(FolderInfo folder, int percentage) { - runOnUiThread(() -> { - mBinding.mainContent.mainIndexProgressBarLabel.setText("index update, folder " - + folder.getLabel() + " " + percentage + "% synchronized"); - updateFolderListView(); - }); - } - - @Override - public void onIndexUpdateComplete() { - runOnUiThread(() -> { - mBinding.mainContent.mainIndexProgressBar.setVisibility(View.GONE); - updateFolderListView(); - }); - } - }); - return null; - } - - @Override - protected void onPostExecute(Void voidd) { - cancelLoadingDialog(); - if (mLibraryHandler.getSyncthingClient() == null) { - Toast.makeText(MainActivity.this, "error starting syncthing client", Toast.LENGTH_LONG).show(); - MainActivity.this.finish(); - } else { - showAllFoldersListView(); - Date lastUpdate = getLastIndexUpdateFromPref(); - if (lastUpdate == null || new Date().getTime() - lastUpdate.getTime() > 10 * 60 * 1000) { //trigger update if last was more than 10mins ago - Log.d("onCreate", "trigger index update, last was " + lastUpdate); - updateIndexFromRemote(); - } - initDeviceList(); - } - } - }.execute(); } private void checkPermissions() { @@ -224,7 +172,7 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On } private void cleanCacheAndIndex() { - mLibraryHandler.getSyncthingClient().clearCacheAndIndex(); + getSyncthingClient().clearCacheAndIndex(); recreate(); } @@ -238,7 +186,7 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On } private void doUpload(final String syncthingFolder, final String syncthingSubFolder, final Uri fileToUpload) { - new UploadFileTask(this, mLibraryHandler.getSyncthingClient(), fileToUpload, syncthingFolder, + new UploadFileTask(this, getSyncthingClient(), fileToUpload, syncthingFolder, syncthingSubFolder, this::updateFolderListView).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } @@ -253,7 +201,7 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On indexBrowser = null; } - List> list = Lists.newArrayList(mLibraryHandler.getFolderBrowser().getFolderInfoAndStatsList()); + List> list = Lists.newArrayList(getFolderBrowser().getFolderInfoAndStatsList()); Collections.sort(list, Ordering.natural().onResultOf(input -> input.getLeft().getLabel())); Log.i(TAG, "list folders = " + list + " (" + list.size() + " records"); ArrayAdapter> adapter = new FoldersListAdapter(this, list); @@ -277,7 +225,7 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On indexBrowser.close(); } Log.d(TAG, "open new index browser"); - indexBrowser = mLibraryHandler.getSyncthingClient().getIndexHandler() + indexBrowser = getSyncthingClient().getIndexHandler() .newIndexBrowserBuilder() .setOrdering(FileInfoOrdering.ALPHA_ASC_DIR_FIRST) .includeParentInList(true).allowParentInRoot(true) @@ -308,8 +256,34 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On } private void cancelLoadingDialog() { - mLoadingDialog.cancel(); - mLoadingDialog = null; + if (mLoadingDialog != null) { + mLoadingDialog.cancel(); + mLoadingDialog = null; + } + } + + @Override + public void onIndexUpdateProgress(FolderInfo folder, int percentage) { + mBinding.mainContent.mainIndexProgressBarLabel.setText("index update, folder " + + folder.getLabel() + " " + percentage + "% synchronized"); + updateFolderListView(); + } + + @Override + public void onIndexUpdateComplete() { + mBinding.mainContent.mainIndexProgressBar.setVisibility(View.GONE); + updateFolderListView(); + } + + @Override + public void onLibraryLoaded() { + showAllFoldersListView(); + Date lastUpdate = getLastIndexUpdateFromPref(); + if (lastUpdate == null || new Date().getTime() - lastUpdate.getTime() > 10 * 60 * 1000) { //trigger update if last was more than 10mins ago + Log.d("onCreate", "trigger index update, last was " + lastUpdate); + updateIndexFromRemote(); + } + initDeviceList(); } private void navigateToFolder(FileInfo fileInfo) { @@ -325,7 +299,7 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On new AsyncTask() { @Override protected void onPreExecute() { - showLoadingDialog("open directory: " + (indexBrowser.isRoot() ? mLibraryHandler.getFolderBrowser().getFolderInfo(indexBrowser.getFolder()).getLabel() : indexBrowser.getCurrentPathFileName())); + showLoadingDialog("open directory: " + (indexBrowser.isRoot() ? getFolderBrowser().getFolderInfo(indexBrowser.getFolder()).getLabel() : indexBrowser.getCurrentPathFileName())); } @Override @@ -352,7 +326,7 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On adapter.notifyDataSetChanged(); mBinding.mainContent.mainFolderAndFilesListView.setSelection(0); mBinding.mainContent.mainHeaderFolderLabel.setText(indexBrowser.isRoot() - ?mLibraryHandler.getFolderBrowser().getFolderInfo(indexBrowser.getFolder()).getLabel() + ?getFolderBrowser().getFolderInfo(indexBrowser.getFolder()).getLabel() :newFileInfo.getFileName()); } } else { @@ -389,7 +363,7 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On .setTitle("remove device " + deviceId.substring(0, 7)) .setMessage("remove device" + deviceId.substring(0, 7) + " from list of known devices?") .setPositiveButton(android.R.string.yes, (dialog, which) -> { - mLibraryHandler.getConfiguration().edit().removePeer(deviceId).persistLater(); + getConfiguration().edit().removePeer(deviceId).persistLater(); updateDeviceList(); }) .setNegativeButton(android.R.string.no, null) @@ -402,7 +376,7 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On private void updateDeviceList() { //TODO fix npe when opening drawer before app has fully started (no synclient) - List list = Lists.newArrayList(mLibraryHandler.getSyncthingClient().getDevicesHandler().getDeviceStatsList()); + List list = Lists.newArrayList(getSyncthingClient().getDevicesHandler().getDeviceStatsList()); Collections.sort(list, new Comparator() { final Function fun= Functions.forMap(ImmutableMap.of(DeviceStats.DeviceStatus.OFFLINE,3, DeviceStats.DeviceStatus.ONLINE_INACTIVE,2, DeviceStats.DeviceStatus.ONLINE_ACTIVE,1)); @Override @@ -419,7 +393,7 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On private void pullFile(final FileInfo fileInfo) { Log.i(TAG, "pulling file = " + fileInfo); - new DownloadFileTask(this, mLibraryHandler.getSyncthingClient(), fileInfo).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new DownloadFileTask(this, getSyncthingClient(), fileInfo).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } private final static String LAST_INDEX_UPDATE_TS_PREF = "LAST_INDEX_UPDATE_TS"; @@ -449,7 +423,7 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On @Override protected Exception doInBackground(Void... voidd) { try { - mLibraryHandler.getSyncthingClient().waitForRemoteIndexAquired(); + getSyncthingClient().waitForRemoteIndexAquired(); return null; } catch (InterruptedException ex) { Log.e(TAG, "index dump exception", ex); @@ -478,7 +452,6 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On protected void onDestroy() { super.onDestroy(); new Thread(() -> { - mLibraryHandler.destroy(); if (indexBrowser != null) { indexBrowser.close(); indexBrowser = null; @@ -523,9 +496,9 @@ public class MainActivity extends AppCompatActivity implements ActivityCompat.On private void importDeviceId(String deviceId) { KeystoreHandler.validateDeviceId(deviceId); - boolean modified = mLibraryHandler.getConfiguration().edit().addPeers(new DeviceInfo(deviceId, null)); + boolean modified = getConfiguration().edit().addPeers(new DeviceInfo(deviceId, null)); if (modified) { - mLibraryHandler.getConfiguration().edit().persistLater(); + getConfiguration().edit().persistLater(); Toast.makeText(this, "successfully imported device: " + deviceId, Toast.LENGTH_SHORT).show(); updateDeviceList();//TODO remove this if event triggered (and handler trigger update) updateIndexFromRemote(); diff --git a/app/src/main/java/it/anyplace/syncbrowser/SyncbrowserActivity.java b/app/src/main/java/it/anyplace/syncbrowser/SyncbrowserActivity.java new file mode 100644 index 0000000..f373432 --- /dev/null +++ b/app/src/main/java/it/anyplace/syncbrowser/SyncbrowserActivity.java @@ -0,0 +1,115 @@ +package it.anyplace.syncbrowser; + +import android.app.AlertDialog; +import android.databinding.DataBindingUtil; +import android.os.AsyncTask; +import android.os.Handler; +import android.support.v7.app.AppCompatActivity; + +import it.anyplace.sync.bep.FolderBrowser; +import it.anyplace.sync.client.SyncthingClient; +import it.anyplace.sync.core.beans.FolderInfo; +import it.anyplace.sync.core.configuration.ConfigurationService; +import it.anyplace.syncbrowser.databinding.DialogLoadingBinding; + +public abstract class SyncbrowserActivity extends AppCompatActivity { + + private static final int SHUTDOWN_LIBRARY_DELAY = 60 * 1000; + + private static int mActivityCount = 0; + private static LibraryHandler mLibraryHandler; + + private AlertDialog mLoadingDialog; + + @Override + protected void onStart() { + super.onStart(); + mActivityCount++; + if (mLibraryHandler == null) { + initLibrary(); + } + } + + @Override + protected void onStop() { + super.onStop(); + mActivityCount--; + new Handler().postDelayed(this::tryShutdownLibrary, SHUTDOWN_LIBRARY_DELAY); + } + + private void initLibrary() { + new AsyncTask() { + + @Override + protected void onPreExecute() { + onLoadingLibrary(); + } + + @Override + protected Void doInBackground(Void... voidd) { + mLibraryHandler = new LibraryHandler(); + mLibraryHandler.init(SyncbrowserActivity.this); + return null; + } + + @Override + protected void onPostExecute(Void voidd) { + mLoadingDialog.cancel(); + mLibraryHandler.setOnIndexUpdatedListener(new LibraryHandler.OnIndexUpdatedListener() { + @Override + public void onIndexUpdateProgress(FolderInfo folder, int percentage) { + onIndexUpdateProgress(folder, percentage); + } + + @Override + public void onIndexUpdateComplete() { + onIndexUpdateComplete(); + } + }); + onLibraryLoaded(); + } + }.execute(); + } + + private void tryShutdownLibrary() { + new Thread(() -> { + if (mActivityCount == 0) { + mLibraryHandler.destroy(); + mLibraryHandler = null; + } + }).start(); + } + + public SyncthingClient getSyncthingClient() { + return mLibraryHandler.getSyncthingClient(); + } + + public ConfigurationService getConfiguration() { + return mLibraryHandler.getConfiguration(); + } + + public FolderBrowser getFolderBrowser() { + return mLibraryHandler.getFolderBrowser(); + } + + @SuppressWarnings("unused") + public void onIndexUpdateProgress(FolderInfo folder, int percentage) { + } + + @SuppressWarnings("unused") + public void onIndexUpdateComplete() { + } + + public void onLoadingLibrary() { + DialogLoadingBinding binding = DataBindingUtil.inflate( + getLayoutInflater(), R.layout.dialog_loading, null, false); + binding.loadingText.setText("loading config, starting syncthing client"); + mLoadingDialog = new android.app.AlertDialog.Builder(this) + .setCancelable(false) + .setView(binding.getRoot()) + .show(); + } + + public void onLibraryLoaded() { + } +}