diff --git a/build.gradle b/build.gradle index 95feb34..dffdf7e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,6 @@ def version = '1.3.7' -def versionNum = 9000013 +def versionNum = 9000015 +def webInstallDir = "${project.buildDir}/web" buildscript { repositories { @@ -33,7 +34,7 @@ android { externalNativeBuild.cmake { targets 'transmissionbtc' - arguments "-DTR_SRC_DIR=${project.buildDir}/transmission" + arguments "-DTR_SRC_DIR=${project.buildDir}/transmission", "-DTR_WEB_INSTALL_DIR=${webInstallDir}" } ndk { @@ -87,7 +88,8 @@ android { } applicationVariants.all { v -> - tasks["merge${v.name.capitalize()}Assets"].dependsOn(generateAssets) + tasks["merge${v.name.capitalize()}Assets"].dependsOn("mergeWebAssets${v.name.capitalize()}") + tasks["mergeWebAssets${v.name.capitalize()}"].dependsOn("externalNativeBuild${v.name.capitalize()}") } lintOptions { @@ -108,7 +110,7 @@ task cleanAll(type: Delete) { delete file(".cxx") } -task generateAssets() { +task mergeWebAssets() { doLast { def webDir = "${project.buildDir}/assets/web" def arch = file("${project.buildDir}/web-control.tar.gz") @@ -119,9 +121,8 @@ task generateAssets() { } copy { - from "${project.buildDir}/transmission/web" + from "${webInstallDir}/usr/local/share/transmission/public_html" into webDir - exclude '*.am', '*.in', '*.scss' } copy { @@ -145,3 +146,9 @@ task generateAssets() { } } } + +task mergeWebAssetsRelease(dependsOn: mergeWebAssets) { +} + +task mergeWebAssetsDebug(dependsOn: mergeWebAssets) { +} diff --git a/cmake/Transmission.cmake b/cmake/Transmission.cmake index ccb1b01..54b6cb6 100644 --- a/cmake/Transmission.cmake +++ b/cmake/Transmission.cmake @@ -6,7 +6,7 @@ option(TR_SRC_DIR "Transmission sources" "${CMAKE_CURRENT_BINARY_DIR}/transmissi set(TR_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/transmission/src/transmission-build") set(TR_CMAKE_ARGS -DENABLE_TESTS=OFF -DENABLE_DAEMON=OFF -DINSTALL_DOC=OFF -DENABLE_UTILS=OFF -DENABLE_CLI=OFF -DENABLE_GTK=OFF -DENABLE_QT=OFF -DENABLE_MAC=OFF -DINSTALL_DOC=OFF - ${EXT_CMAKE_ARGS}) + -DENABLE_WEB=ON ${EXT_CMAKE_ARGS}) set(TR_LIBRARIES "${TR_BUILD_DIR}/libtransmission/libtransmission.a" @@ -31,7 +31,7 @@ ExternalProject_Add(transmission GIT_SUBMODULES_RECURSE 1 CONFIGURE_COMMAND ${CMAKE_COMMAND} ${TR_SRC_DIR} ${TR_CMAKE_ARGS} BUILD_COMMAND ${MAKE_EXE} -j${NCPU} - INSTALL_COMMAND echo "Skip install" + INSTALL_COMMAND ${MAKE_EXE} install "DESTDIR=${TR_WEB_INSTALL_DIR}" BUILD_BYPRODUCTS ${TR_LIBRARIES}) add_dependencies(transmission openssl curl libevent) diff --git a/src/main/java/com/ap/transmission/btc/BindingHelper.java b/src/main/java/com/ap/transmission/btc/BindingHelper.java index ac1bdab..5db9496 100644 --- a/src/main/java/com/ap/transmission/btc/BindingHelper.java +++ b/src/main/java/com/ap/transmission/btc/BindingHelper.java @@ -39,14 +39,6 @@ public boolean and(boolean... bools) { return true; } - public boolean isPro() { - return Utils.isPro(); - } - - public boolean isBasic() { - return Utils.isBasic(); - } - public String getIp() { return Utils.getIPAddress(getActivity()); } @@ -70,16 +62,13 @@ public boolean isSuspended() { public void startStopService(final View... disable) { final boolean running = isServiceRunning(); for (View v : disable) v.setEnabled(false); - Runnable callback = new Runnable() { - @Override - public void run() { - for (View v : disable) v.setEnabled(true); - isServiceRunning = TransmissionService.isRunning() ? (byte) 1 : 0; - invalidate(); - - if (!running && !isServiceRunning()) { - Utils.showErr(disable[0], R.string.err_failed_to_start_transmission); - } + Runnable callback = () -> { + for (View v : disable) v.setEnabled(true); + isServiceRunning = TransmissionService.isRunning() ? (byte) 1 : 0; + invalidate(); + + if (!running && !isServiceRunning()) { + Utils.showErr(disable[0], R.string.err_failed_to_start_transmission); } }; diff --git a/src/main/java/com/ap/transmission/btc/Prefs.java b/src/main/java/com/ap/transmission/btc/Prefs.java index 1e76429..05ae37b 100644 --- a/src/main/java/com/ap/transmission/btc/Prefs.java +++ b/src/main/java/com/ap/transmission/btc/Prefs.java @@ -9,7 +9,6 @@ import com.ap.transmission.btc.func.Function; import java.io.File; -import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -27,7 +26,6 @@ import static com.ap.transmission.btc.Prefs.K.ENABLE_UPNP; import static com.ap.transmission.btc.Prefs.K.ENABLE_WATCH_DIR; import static com.ap.transmission.btc.Prefs.K.ENCR_MODE; -import static com.ap.transmission.btc.Prefs.K.FOREGROUND; import static com.ap.transmission.btc.Prefs.K.HTTP_SERVER_PORT; import static com.ap.transmission.btc.Prefs.K.INCREASE_SO_BUF; import static com.ap.transmission.btc.Prefs.K.RPC_PASSWD; @@ -47,18 +45,10 @@ */ public class Prefs { public enum K { - SETTINGS_DIR(new Function() { - public Object apply(Prefs p) { return p.getDefaultSettingsDir(); } - }), - DOWNLOAD_DIR(new Function() { - public Object apply(Prefs p) { return p.getDefaultDownloadDir(); } - }), - PREV_DOWNLOAD_DIR(new Function() { - public Object apply(Prefs p) { return p.getDownloadDir(); } - }), - WATCH_DIR(new Function() { - public Object apply(Prefs p) { return p.getDefaultWatchDir(); } - }), + SETTINGS_DIR(Prefs::getDefaultSettingsDir), + DOWNLOAD_DIR(Prefs::getDefaultDownloadDir), + PREV_DOWNLOAD_DIR(Prefs::getDownloadDir), + WATCH_DIR(Prefs::getDefaultWatchDir), START_ON_BOOT(false), BOOT_DELAY(0), ENABLE_WATCH_DIR(false), @@ -83,7 +73,6 @@ public enum K { HTTP_SERVER_PORT(9092), WIFI_ETH_ONLY(true), WIFI_SSID(""), - FOREGROUND(true), UUID(new Function() { public Object apply(Prefs p) { String uuid = java.util.UUID.randomUUID().toString(); @@ -198,8 +187,6 @@ private Object getObject(K k) { return isWifiEthOnly(); case WIFI_SSID: return getWifiSsid(); - case FOREGROUND: - return isForeground(); default: return getString(k); } @@ -269,7 +256,7 @@ public void set(K k, Object value) { setSeqDownloadEnabled((Boolean) value); break; case ENABLE_UPNP: - setUpnpEnabled(Boolean.valueOf(value.toString())); + setUpnpEnabled(Boolean.parseBoolean(value.toString())); break; case HTTP_SERVER_PORT: setHttpServerPort(value.toString()); @@ -280,9 +267,6 @@ public void set(K k, Object value) { case WIFI_SSID: setWifiSsid(value.toString()); break; - case FOREGROUND: - setForeground((Boolean) value); - break; default: putString(k, value.toString()); } @@ -334,11 +318,7 @@ public void setDownloadDir(CharSequence dir) { } public boolean isWatchDirEnabled() { - if (Utils.isBasic()) { - return getBoolean(ENABLE_WATCH_DIR); - } else { - return prefs.getString(K.WATCH_DIR.id(0), null) != null; - } + return prefs.getString(K.WATCH_DIR.id(0), null) != null; } public void setWatchDirEnabled(boolean enabled) { @@ -367,7 +347,6 @@ private String getDefaultWatchDir() { public Map getWatchDirs() { - if (Utils.isBasic()) return Collections.singletonMap(getWatchDir(), getDownloadDir()); Map m = new HashMap<>(); for (int i = 0; ; i++) { @@ -551,21 +530,13 @@ public void setWifiSsid(CharSequence list) { putString(WIFI_SSID, list.toString().trim()); } - public boolean isForeground() { - return getBoolean(FOREGROUND); - } - - public void setForeground(boolean foreground) { - putBoolean(FOREGROUND, foreground); - } - public String getUUID() { return getString(UUID); } public String getString(K k) { String s = prefs.getString(k.id(), null); - return (s == null) || s.isEmpty() ? k.def(this) : s; + return (s == null) || s.isEmpty() ? k.def(this) : s; } public String getString(K k, int index, String def) { @@ -614,7 +585,8 @@ public int getInt(K k) { public void putInt(K k, CharSequence value) { try { putInt(k, Integer.parseInt(value.toString())); - } catch (NumberFormatException ignore) {} + } catch (NumberFormatException ignore) { + } } public void putInt(K k, int value) { @@ -638,7 +610,8 @@ private static File selectMaxSize(File[] files) { if (f == null) continue; StatFs stat = new StatFs(f.getAbsolutePath()); if (maxLen < stat.getTotalBytes()) max = f; - } catch (IllegalArgumentException ignore) {} + } catch (IllegalArgumentException ignore) { + } } return max; diff --git a/src/main/java/com/ap/transmission/btc/Utils.java b/src/main/java/com/ap/transmission/btc/Utils.java index d662a20..89f3ab7 100644 --- a/src/main/java/com/ap/transmission/btc/Utils.java +++ b/src/main/java/com/ap/transmission/btc/Utils.java @@ -91,8 +91,6 @@ public class Utils { public static final Charset UTF8 = Charset.forName("UTF-8"); private static final String TAG = Utils.class.getName(); @SuppressWarnings("ConstantConditions") - private static final boolean isPro = BUILD_TYPE.endsWith("pro"); - private static final boolean isBasic = BUILD_TYPE.endsWith("basic"); private static final boolean isDebugEnabled = BUILD_TYPE.startsWith("debug"); private static volatile InetAddress ifaddr; @@ -220,6 +218,8 @@ public static String getRealDirPath(Context ctx, Uri dirUri) { if (VERSION.SDK_INT < VERSION_CODES.LOLLIPOP) return null; ParcelFileDescriptor pfd = null; DocumentFile dir = DocumentFile.fromTreeUri(ctx, dirUri); + if (dir == null) return null; + String rndName = "transmissionbtc-" + UUID.randomUUID() + ".tmp"; DocumentFile f = dir.createFile(StorageAccess.MIME_TYPE, rndName); @@ -294,14 +294,6 @@ public static boolean hasWritePerms(File dir) { } } - public static boolean isPro() { - return isPro; - } - - public static boolean isBasic() { - return isBasic; - } - public static boolean isDebugEnabled() { return isDebugEnabled; } @@ -437,19 +429,11 @@ private static void copyAssets(AssetManager amgr, String src, File dstDir, byte[ File dst = new File(dstDir, src); debug(TAG, "Copying assets %s -> %s", src, dst); mkdirs(dst.getParentFile()); - InputStream in = null; - OutputStream out = null; - - try { - in = amgr.open(src); - out = new FileOutputStream(dst); + try (InputStream in = amgr.open(src); OutputStream out = new FileOutputStream(dst)) { for (int i = in.read(buf); i != -1; i = in.read(buf)) { out.write(buf, 0, i); } - } finally { - if (in != null) in.close(); - if (out != null) out.close(); } } } @@ -474,15 +458,11 @@ public static int exec(long timeout, final InputStream script, List cmd) @Override public void run() { if (script != null) { - OutputStream out = p.getOutputStream(); - byte[] buf = new byte[1024]; - - try { + try (OutputStream out = p.getOutputStream()) { + byte[] buf = new byte[1024]; for (int i = script.read(buf); i != -1; i = script.read(buf)) out.write(buf, 0, i); } catch (IOException ex) { Log.e(TAG, ex.getMessage(), ex); - } finally { - try { out.close(); } catch (IOException ignore) {} } } @@ -516,9 +496,8 @@ public void run() { } } - @SuppressWarnings("unchecked") public static Collection splitPath(File path, boolean readable) { - Deque q = new LinkedList(); + Deque q = new LinkedList<>(); q.addFirst(path); for (File p = path.getParentFile(); p != null; p = p.getParentFile()) { @@ -656,7 +635,6 @@ public static String getMimeTypeFromExtension(String fileExt) { return (fileExt == null) ? null : MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExt); } - @SuppressWarnings("BooleanMethodIsAlwaysInverted") public static boolean isWifiEthActive(Context context, String allowedNetworks) { Context ctx = context.getApplicationContext(); ConnectivityManager cmgr = (ConnectivityManager) ctx.getSystemService(CONNECTIVITY_SERVICE); diff --git a/src/main/java/com/ap/transmission/btc/activities/MainActivity.java b/src/main/java/com/ap/transmission/btc/activities/MainActivity.java index 93a00ce..fab7c06 100644 --- a/src/main/java/com/ap/transmission/btc/activities/MainActivity.java +++ b/src/main/java/com/ap/transmission/btc/activities/MainActivity.java @@ -2,7 +2,6 @@ import android.Manifest.permission; import android.app.AlertDialog; -import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.databinding.DataBindingUtil; @@ -72,7 +71,7 @@ public void onTabSelected(TabLayout.Tab tab) { tab.setIcon(tabs[pos].getActiveIcon()); setTitle(tabs[pos].getTitle()); - if (!Utils.isBasic() && (tab.getPosition() == 0)) { + if (tab.getPosition() == 0) { TorrentsList l = findViewById(R.id.torrents_list); if (l != null) l.setActive(true); } @@ -82,14 +81,15 @@ public void onTabSelected(TabLayout.Tab tab) { public void onTabUnselected(TabLayout.Tab tab) { tab.setIcon(tabs[tab.getPosition()].getIcon()); - if (!Utils.isBasic() && (tab.getPosition() == 0)) { + if (tab.getPosition() == 0) { TorrentsList l = findViewById(R.id.torrents_list); if (l != null) l.setActive(false); } } @Override - public void onTabReselected(TabLayout.Tab tab) {} + public void onTabReselected(TabLayout.Tab tab) { + } }); List perms = Arrays.asList(permission.INTERNET, permission.ACCESS_NETWORK_STATE, @@ -108,12 +108,9 @@ public void onTabReselected(TabLayout.Tab tab) {} AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this); alertBuilder.setTitle(R.string.location_perm_title); alertBuilder.setMessage(R.string.location_perm_msg); - alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - checkPermission(l.toArray(new String[l.size()])); - findViewById(R.id.button_start_stop).requestFocus(); - } + alertBuilder.setPositiveButton(android.R.string.yes, (dialog, which) -> { + checkPermission(l.toArray(new String[l.size()])); + findViewById(R.id.button_start_stop).requestFocus(); }); alertBuilder.create().show(); } else { @@ -125,7 +122,7 @@ public void onClick(DialogInterface dialog, int which) { @Override protected void onStop() { super.onStop(); - if (!Utils.isBasic() && (tabLayout.getSelectedTabPosition() == 0)) { + if (tabLayout.getSelectedTabPosition() == 0) { TorrentsList l = findViewById(R.id.torrents_list); if (l != null) l.setActive(false); } @@ -134,7 +131,7 @@ protected void onStop() { @Override protected void onStart() { super.onStart(); - if (!Utils.isBasic() && (tabLayout.getSelectedTabPosition() == 0)) { + if (tabLayout.getSelectedTabPosition() == 0) { TorrentsList l = findViewById(R.id.torrents_list); if (l != null) l.setActive(true); } @@ -180,16 +177,13 @@ private void addFile() { Intent intent = new Intent(getApplicationContext(), SelectFileActivity.class); intent.putExtra(SelectFileActivity.REQUEST_FILE, true); intent.putExtra(SelectFileActivity.REQUEST_PATTERN, ".+\\.torrent"); - setActivityResultHandler(new ActivityResultHandler() { - @Override - public boolean onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode != SelectFileActivity.RESULT_OK) return true; - File f = (File) data.getSerializableExtra(SelectFileActivity.RESULT_FILE); - Intent intent = new Intent(getApplicationContext(), DownloadTorrentActivity.class); - intent.setData(Uri.fromFile(f)); - startActivity(intent); - return true; - } + setActivityResultHandler((requestCode, resultCode, data) -> { + if (resultCode != SelectFileActivity.RESULT_OK) return true; + File f = (File) data.getSerializableExtra(SelectFileActivity.RESULT_FILE); + Intent intent1 = new Intent(getApplicationContext(), DownloadTorrentActivity.class); + intent1.setData(Uri.fromFile(f)); + startActivity(intent1); + return true; }); startActivityForResult(intent, ADD_FILE); } @@ -200,27 +194,19 @@ private void addLink() { builder.setTitle(R.string.torrent_link); builder.setView(input); - builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - String text = input.getText().toString().trim(); - - if (text.isEmpty()) { - Utils.showMsg(input, R.string.msg_enter_link); - addLink(); - } else { - Intent intent = new Intent(getApplicationContext(), DownloadTorrentActivity.class); - intent.setData(Uri.parse(text)); - startActivity(intent); - } - } - }); - builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - dialog.cancel(); + builder.setPositiveButton(android.R.string.ok, (dialog, which) -> { + String text = input.getText().toString().trim(); + + if (text.isEmpty()) { + Utils.showMsg(input, R.string.msg_enter_link); + addLink(); + } else { + Intent intent = new Intent(getApplicationContext(), DownloadTorrentActivity.class); + intent.setData(Uri.parse(text)); + startActivity(intent); } }); + builder.setNegativeButton(android.R.string.cancel, (dialog, which) -> dialog.cancel()); builder.show(); } @@ -306,21 +292,14 @@ private void checkPermission(String... perms) { } static { - if (Utils.isBasic()) { - tabs = new TabInfo[]{ - new TabInfo(R.string.title_settings, R.drawable.settings, R.drawable.settings_active, R.layout.settings), - new TabInfo(R.string.title_about, R.drawable.about, R.drawable.about_active, R.layout.about), - }; - } else { - tabs = new TabInfo[]{ - new TabInfo(R.string.title_downloads, R.drawable.downloads, R.drawable.downloads_active, R.layout.downloads), - new TabInfo(R.string.title_settings, R.drawable.settings, R.drawable.settings_active, R.layout.settings), - new TabInfo(R.string.title_watch_dirs, R.drawable.watch, R.drawable.watch_active, R.layout.watch_dirs), - new TabInfo(R.string.title_proxy, R.drawable.proxy, R.drawable.proxy_active, R.layout.proxy), - // TODO: implement - // new TabInfo(R.string.title_rss, R.drawable.rss, R.drawable.rss_active, R.layout.rss), - new TabInfo(R.string.title_about, R.drawable.about, R.drawable.about_active, R.layout.about), - }; - } + tabs = new TabInfo[]{ + new TabInfo(R.string.title_downloads, R.drawable.downloads, R.drawable.downloads_active, R.layout.downloads), + new TabInfo(R.string.title_settings, R.drawable.settings, R.drawable.settings_active, R.layout.settings), + new TabInfo(R.string.title_watch_dirs, R.drawable.watch, R.drawable.watch_active, R.layout.watch_dirs), + new TabInfo(R.string.title_proxy, R.drawable.proxy, R.drawable.proxy_active, R.layout.proxy), + // TODO: implement + // new TabInfo(R.string.title_rss, R.drawable.rss, R.drawable.rss_active, R.layout.rss), + new TabInfo(R.string.title_about, R.drawable.about, R.drawable.about_active, R.layout.about), + }; } } diff --git a/src/main/java/com/ap/transmission/btc/services/TransmissionService.java b/src/main/java/com/ap/transmission/btc/services/TransmissionService.java index fe210d9..aa20cf9 100644 --- a/src/main/java/com/ap/transmission/btc/services/TransmissionService.java +++ b/src/main/java/com/ap/transmission/btc/services/TransmissionService.java @@ -1,6 +1,5 @@ package com.ap.transmission.btc.services; -import android.annotation.SuppressLint; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -65,6 +64,8 @@ public static void start(Context context, Runnable callback, int delay) { Intent i = new Intent(context, TransmissionService.class); if (delay > 0) i.putExtra(DELAY, delay); + Log.i(TAG, "Starting service"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { context.startForegroundService(i); } else { @@ -90,6 +91,7 @@ public static synchronized void stop(Context context, Runnable callback) { if (runNow) { if (callback != null) callback.run(); } else { + Log.i(TAG, "Stopping service"); context.stopService(new Intent(context, TransmissionService.class)); } } @@ -134,14 +136,10 @@ public void onDestroy() { @Override public int onStartCommand(Intent intent, int flags, int startId) { if (!isRunning()) { - if (transmission.getPrefs().isForeground()) { - runOnStart(new Runnable() { - @Override - public void run() { - foreground(); - } - }); - } + Log.i(TAG, "Start command received"); + Notification n = buildNotification(getApplicationContext(), false); + startForeground(NOTIFICATION_ID, n); + runOnStart(TransmissionService::updateNotification); final int delay = (intent == null) ? 0 : intent.getIntExtra(DELAY, 0); new StartTask(delay).execute((Void) null); @@ -155,15 +153,9 @@ private static void runOnStart(Runnable run) { runOnStart.add(run); } - @SuppressLint("ObsoleteSdkInt") - private void foreground() { - Notification n = buildNotification(getApplicationContext(), !transmission.isSuspended()); - startForeground(NOTIFICATION_ID, n); - } - public static void updateNotification() { Transmission tr = transmission; - if ((tr == null) || !transmission.getPrefs().isForeground()) return; + if (tr == null) return; Context ctx = tr.getContext(); NotificationManager nmgr = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE); if (nmgr == null) return; @@ -171,7 +163,6 @@ public static void updateNotification() { nmgr.notify(NOTIFICATION_ID, n); } - @SuppressLint("ObsoleteSdkInt") static Notification buildNotification(Context ctx, boolean running) { String ip = Utils.getIPAddress(ctx); Intent i = new Intent(ctx, MainActivity.class); @@ -198,12 +189,7 @@ static Notification buildNotification(Context ctx, boolean running) { } } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - return b.build(); - } else { - //noinspection deprecation - return b.getNotification(); - } + return b.build(); } private static final class StartTask extends AsyncTask> { @@ -219,7 +205,8 @@ protected List doInBackground(Void... params) { try { Log.i(TAG, "Waiting " + delay + " seconds before start"); Thread.sleep(delay * 1000); - } catch (InterruptedException ignore) {} + } catch (InterruptedException ignore) { + } } Transmission t; diff --git a/src/main/java/com/ap/transmission/btc/torrent/Transmission.java b/src/main/java/com/ap/transmission/btc/torrent/Transmission.java index 2fbdcfb..7749df1 100644 --- a/src/main/java/com/ap/transmission/btc/torrent/Transmission.java +++ b/src/main/java/com/ap/transmission/btc/torrent/Transmission.java @@ -181,47 +181,11 @@ public void start() throws IOException { if (hasDownloadingTorrents()) wakeLock(); // Handle callbacks in a separate thread to avoid dead locks - Native.transmissionSetRpcCallbacks(new Runnable() { - @Override - public void run() { - getExecutor().submit(new Runnable() { - @Override - public void run() { - torrentAddedOrChanged(); - } - }); - } - }, new Runnable() { - @Override - public void run() { - getExecutor().submit(new Runnable() { - @Override - public void run() { - torrentRemoved(); - } - }); - } - }, new Runnable() { - @Override - public void run() { - getExecutor().submit(new Runnable() { - @Override - public void run() { - sessionChanged(); - } - }); - } - }, new Runnable() { - @Override - public void run() { - getExecutor().submit(new Runnable() { - @Override - public void run() { - cheduledAltSpeed(); - } - }); - } - }); + Native.transmissionSetRpcCallbacks( + () -> getExecutor().submit(this::torrentAddedOrChanged), + () -> getExecutor().submit(this::torrentRemoved), + () -> getExecutor().submit(this::sessionChanged), + () -> getExecutor().submit(this::cheduledAltSpeed)); ok = true; } finally { @@ -241,16 +205,13 @@ private void startWatchers() { if (interval > 0) { ScheduledExecutorService sched = getScheduler(); - sched.scheduleWithFixedDelay(new Runnable() { - @Override - public void run() { - readLock().lock(); - try { - if (!isRunning() || (watchers == null)) return; - for (Watcher w : watchers) w.scan(); - } finally { - readLock().unlock(); - } + sched.scheduleWithFixedDelay(() -> { + readLock().lock(); + try { + if (!isRunning() || (watchers == null)) return; + for (Watcher w : watchers) w.scan(); + } finally { + readLock().unlock(); } }, interval, interval, TimeUnit.SECONDS); } @@ -544,7 +505,10 @@ private void increaseSoBuf() { } catch (IOException ex) { err(TAG, ex, "Failed to open asset: %s", file); } finally { - if (in != null) try { in.close(); } catch (IOException ignore) {} + if (in != null) try { + in.close(); + } catch (IOException ignore) { + } } } @@ -556,7 +520,7 @@ public ExecutorService getExecutor() { try { if ((exec = executor) == null) { executor = exec = new ThreadPoolExecutor(0, - 30, 60L, TimeUnit.SECONDS, new SynchronousQueue(), + 30, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(), Executors.defaultThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy()); } } finally { @@ -575,7 +539,8 @@ private void stopExecutor() { try { exec.shutdownNow(); exec.awaitTermination(30, TimeUnit.SECONDS); - } catch (InterruptedException ignore) {} + } catch (InterruptedException ignore) { + } } public ScheduledExecutorService getScheduler() { @@ -604,7 +569,8 @@ private void stopSheduler() { try { sched.shutdownNow(); sched.awaitTermination(30, TimeUnit.SECONDS); - } catch (InterruptedException ignore) {} + } catch (InterruptedException ignore) { + } } @SuppressLint("WakelockTimeout") @@ -618,24 +584,21 @@ private void wakeLock() { powerLock = pl; debug(TAG, "WakeLock acquired"); - final ScheduledFuture f[] = new ScheduledFuture[1]; - f[0] = getScheduler().scheduleWithFixedDelay(new Runnable() { - @Override - public void run() { - if (!hasDownloadingTorrents()) { - writeLock().lock(); - try { - if (!isRunning()) { - wakeUnlock(); - f[0].cancel(false); - } else if (!Native.transmissionHasDownloadingTorrents(session)) { - debug(TAG, "No active downloads - releasing WakeLock"); - wakeUnlock(); - f[0].cancel(false); - } - } finally { - writeLock().unlock(); + final ScheduledFuture[] f = new ScheduledFuture[1]; + f[0] = getScheduler().scheduleWithFixedDelay(() -> { + if (!hasDownloadingTorrents()) { + writeLock().lock(); + try { + if (!isRunning()) { + wakeUnlock(); + f[0].cancel(false); + } else if (!Native.transmissionHasDownloadingTorrents(session)) { + debug(TAG, "No active downloads - releasing WakeLock"); + wakeUnlock(); + f[0].cancel(false); } + } finally { + writeLock().unlock(); } } }, 1, 1, TimeUnit.MINUTES); diff --git a/src/main/res/layout/settings.xml b/src/main/res/layout/settings.xml index 7f1b80a..c65e62b 100644 --- a/src/main/res/layout/settings.xml +++ b/src/main/res/layout/settings.xml @@ -47,54 +47,11 @@ app:select_dir="true" app:title="@string/settings_dir" /> - - - @@ -103,7 +60,7 @@ android:layout_height="wrap_content" android:layout_columnSpan="2" android:layout_gravity="fill_horizontal" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:text="@string/wifi_eth_only_ssid" android:textStyle="bold" android:visibility="@{p.wifiEthOnly}" /> @@ -112,7 +69,7 @@ android:layout_height="wrap_content" android:layout_columnSpan="2" android:layout_gravity="fill_horizontal" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:hint="Home WiFi, Guest WiFi" android:inputType="text" android:maxLines="1" @@ -124,31 +81,20 @@ android:layout_height="wrap_content" android:layout_gravity="fill_horizontal" android:text="@string/encr_mode" - android:textStyle="bold" - android:visibility="@{!h.basic}" /> + android:textStyle="bold" /> - - - + android:background="@drawable/separator" /> @@ -172,7 +118,7 @@ android:layout_height="wrap_content" android:layout_gravity="end" android:focusable="true" - android:gravity="right" + android:gravity="end" android:inputType="numberDecimal" android:maxLength="5" android:minEms="2" @@ -183,7 +129,7 @@ android:layout_width="match_parent" android:layout_height="1dp" android:layout_columnSpan="2" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:background="@drawable/separator" android:visibility="@{p.startOnBoot}" /> @@ -192,7 +138,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_columnSpan="2" - android:visibility="@{!h.basic}" app:onClick="@{h::checkRoot}" app:pref="@{K.INCREASE_SO_BUF}" app:text="@string/increase_so_buf" /> @@ -202,7 +147,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_columnSpan="2" - android:visibility="@{!h.basic}" app:pref="@{K.ENABLE_SEQ_DOWNLOAD}" app:text="@string/enable_seq_download" /> @@ -211,50 +155,48 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_columnSpan="2" - android:visibility="@{!h.basic}" app:pref="@{K.ENABLE_UPNP}" app:text="@string/enable_upnp" /> + android:visibility="@{p.upnpEnabled}" /> + android:visibility="@{p.upnpEnabled}" /> @@ -263,7 +205,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="end" - android:gravity="right" + android:gravity="end" android:inputType="numberDecimal" android:maxLength="5" android:minEms="2" @@ -274,7 +216,7 @@ android:layout_width="match_parent" android:layout_height="1dp" android:layout_columnSpan="2" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:background="@drawable/separator" android:visibility="@{p.rpcEnabled}" /> @@ -283,7 +225,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_columnSpan="2" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:visibility="@{p.rpcEnabled}" app:pref="@{K.ENABLE_ALT_WEB_UI}" app:text="@string/enable_alt_web_ui" /> @@ -292,7 +234,7 @@ android:layout_width="match_parent" android:layout_height="1dp" android:layout_columnSpan="2" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:background="@drawable/separator" android:visibility="@{p.rpcEnabled}" /> @@ -301,7 +243,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_columnSpan="2" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:visibility="@{p.rpcEnabled}" app:pref="@{K.ENABLE_RPC_AUTH}" app:text="@string/auth_required" /> @@ -311,7 +253,7 @@ android:layout_height="wrap_content" android:layout_columnSpan="2" android:layout_gravity="fill_horizontal" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:text="@string/username" android:textStyle="bold" android:visibility="@{h.and(p.rpcEnabled, p.rpcAuthEnabled)}" /> @@ -320,7 +262,7 @@ android:layout_height="wrap_content" android:layout_columnSpan="2" android:layout_gravity="fill_horizontal" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:inputType="text" android:maxLines="1" android:visibility="@{h.and(p.rpcEnabled, p.rpcAuthEnabled)}" @@ -331,7 +273,7 @@ android:layout_height="wrap_content" android:layout_columnSpan="2" android:layout_gravity="fill_horizontal" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:text="@string/password" android:textStyle="bold" android:visibility="@{h.and(p.rpcEnabled, p.rpcAuthEnabled)}" /> @@ -340,7 +282,7 @@ android:layout_height="wrap_content" android:layout_columnSpan="2" android:layout_gravity="fill_horizontal" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:inputType="textPassword" android:maxLines="1" android:visibility="@{h.and(p.rpcEnabled, p.rpcAuthEnabled)}" @@ -351,7 +293,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_columnSpan="2" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:visibility="@{p.rpcEnabled}" app:pref="@{K.ENABLE_RPC_WHITELIST}" app:text="@string/enable_rpc_whitelist" /> @@ -360,7 +302,7 @@ android:layout_height="wrap_content" android:layout_columnSpan="2" android:layout_gravity="fill_horizontal" - android:layout_marginLeft="10dp" + android:layout_marginStart="10dp" android:inputType="text" android:maxLines="1" android:visibility="@{h.and(p.rpcEnabled, p.rpcWhitelistEnabled)}"