diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/SSLSocketFactory.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/SSLSocketFactory.java deleted file mode 100644 index 4f87e1ea..00000000 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/SSLSocketFactory.java +++ /dev/null @@ -1,373 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ - -package org.moire.ultrasonic.service.ssl; - -import org.apache.http.conn.ConnectTimeoutException; -import org.apache.http.conn.scheme.HostNameResolver; -import org.apache.http.conn.scheme.LayeredSocketFactory; -import org.apache.http.conn.ssl.AllowAllHostnameVerifier; -import org.apache.http.conn.ssl.X509HostnameVerifier; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketTimeoutException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.UnrecoverableKeyException; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import javax.net.ssl.X509TrustManager; - -/** - * Layered socket factory for TLS/SSL connections. - *

- * SSLSocketFactory can be used to validate the identity of the HTTPS server against a list of - * trusted certificates and to authenticate to the HTTPS server using a private key. - *

- * SSLSocketFactory will enable server authentication when supplied with - * a {@link KeyStore trust-store} file containing one or several trusted certificates. The client - * secure socket will reject the connection during the SSL session handshake if the target HTTPS - * server attempts to authenticate itself with a non-trusted certificate. - *

- * Use JDK keytool utility to import a trusted certificate and generate a trust-store file: - *

- *     keytool -import -alias "my server cert" -file server.crt -keystore my.truststore
- *    
- *

- * In special cases the standard trust verification process can be bypassed by using a custom - * {@link TrustStrategy}. This interface is primarily intended for allowing self-signed - * certificates to be accepted as trusted without having to add them to the trust-store file. - *

- * The following parameters can be used to customize the behavior of this - * class: - *

- *

- * SSLSocketFactory will enable client authentication when supplied with - * a {@link KeyStore key-store} file containing a private key/public certificate - * pair. The client secure socket will use the private key to authenticate - * itself to the target HTTPS server during the SSL session handshake if - * requested to do so by the server. - * The target HTTPS server will in its turn verify the certificate presented - * by the client in order to establish client's authenticity - *

- * Use the following sequence of actions to generate a key-store file - *

- * - * - * @since 4.0 - */ -public class SSLSocketFactory implements LayeredSocketFactory -{ - - public static final String TLS = "TLS"; - public static final X509HostnameVerifier ALLOW_ALL_HOSTNAME_VERIFIER = new AllowAllHostnameVerifier(); - - /** - * The default factory using the default JVM settings for secure connections. - */ - private final javax.net.ssl.SSLSocketFactory socketFactory; - private final HostNameResolver nameResolver; - private volatile X509HostnameVerifier hostnameVerifier; - - private static SSLContext createSSLContext(String algorithm, final KeyStore keystore, final String keyStorePassword, final SecureRandom random, final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, KeyManagementException - { - if (algorithm == null) - { - algorithm = TLS; - } - - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - keyManagerFactory.init(keystore, keyStorePassword != null ? keyStorePassword.toCharArray() : null); - KeyManager[] keyManagers = keyManagerFactory.getKeyManagers(); - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - trustManagerFactory.init(keystore); - - TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); - - if (trustManagers != null && trustStrategy != null) - { - for (int i = 0; i < trustManagers.length; i++) - { - TrustManager tm = trustManagers[i]; - - if (tm instanceof X509TrustManager) - { - trustManagers[i] = new TrustManagerDecorator((X509TrustManager) tm, trustStrategy); - } - } - } - - SSLContext sslcontext = SSLContext.getInstance(algorithm); - sslcontext.init(keyManagers, trustManagers, random); - - return sslcontext; - } - - /** - * @since 4.1 - */ - public SSLSocketFactory(String algorithm, final KeyStore keystore, final String keyStorePassword, final SecureRandom random, final TrustStrategy trustStrategy, final X509HostnameVerifier hostnameVerifier) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException - { - this(createSSLContext(algorithm, keystore, keyStorePassword, random, trustStrategy), hostnameVerifier); - } - - /** - * @since 4.1 - */ - public SSLSocketFactory(final TrustStrategy trustStrategy, final X509HostnameVerifier hostnameVerifier) throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException - { - this(TLS, null, null, null, trustStrategy, hostnameVerifier); - } - - /** - * @since 4.1 - */ - public SSLSocketFactory(final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) - { - super(); - this.socketFactory = sslContext.getSocketFactory(); - this.hostnameVerifier = hostnameVerifier; - this.nameResolver = null; - } - - @SuppressWarnings("cast") - public Socket createSocket() throws IOException - { - // the cast makes sure that the factory is working as expected - return this.socketFactory.createSocket(); - } - - /** - * @since 4.1 - */ - public Socket connectSocket(final Socket sock, final InetSocketAddress remoteAddress, final InetSocketAddress localAddress, final HttpParams params) throws IOException - { - if (remoteAddress == null) - { - throw new IllegalArgumentException("Remote address may not be null"); - } - - if (params == null) - { - throw new IllegalArgumentException("HTTP parameters may not be null"); - } - - SSLSocket sslSocket = (SSLSocket) (sock != null ? sock : createSocket()); - - if (localAddress != null) - { - // sslSocket.setReuseAddress(HttpConnectionParams.getSoReuseaddr(params)); - sslSocket.bind(localAddress); - } - - int connTimeout = HttpConnectionParams.getConnectionTimeout(params); - int soTimeout = HttpConnectionParams.getSoTimeout(params); - - try - { - sslSocket.connect(remoteAddress, connTimeout); - } - catch (SocketTimeoutException ex) - { - throw new ConnectTimeoutException(String.format("Connect to %s/%s timed out", remoteAddress.getHostName(), remoteAddress.getAddress())); - } - - sslSocket.setSoTimeout(soTimeout); - - if (this.hostnameVerifier != null) - { - try - { - this.hostnameVerifier.verify(remoteAddress.getHostName(), sslSocket); - // verifyHostName() didn't blowup - good! - } - catch (IOException iox) - { - // close the socket before re-throwing the exception - try - { - sslSocket.close(); - } - catch (Exception x) - { /*ignore*/ } - throw iox; - } - } - - return sslSocket; - } - - - /** - * Checks whether a socket connection is secure. - * This factory creates TLS/SSL socket connections - * which, by default, are considered secure. - *
- * Derived classes may override this method to perform - * runtime checks, for example based on the cypher suite. - * - * @param sock the connected socket - * @return true - * @throws IllegalArgumentException if the argument is invalid - */ - public boolean isSecure(final Socket sock) throws IllegalArgumentException - { - if (sock == null) - { - throw new IllegalArgumentException("Socket may not be null"); - } - - // This instanceof check is in line with createSocket() above. - if (!(sock instanceof SSLSocket)) - { - throw new IllegalArgumentException("Socket not created by this factory"); - } - - // This check is performed last since it calls the argument object. - if (sock.isClosed()) - { - throw new IllegalArgumentException("Socket is closed"); - } - - return true; - } - - /** - * @since 4.1 - */ - public Socket createLayeredSocket(final Socket socket, final String host, final int port, final boolean autoClose) throws IOException - { - SSLSocket sslSocket = (SSLSocket) this.socketFactory.createSocket(socket, host, port, autoClose); - - if (this.hostnameVerifier != null) - { - this.hostnameVerifier.verify(host, sslSocket); - } - - // verifyHostName() didn't blowup - good! - return sslSocket; - } - - /** - * @deprecated Use {@link #connectSocket(Socket, InetSocketAddress, InetSocketAddress, HttpParams)} - */ - @Deprecated - public Socket connectSocket(final Socket socket, final String host, int port, final InetAddress localAddress, int localPort, final HttpParams params) throws IOException - { - InetSocketAddress local = null; - - if (localAddress != null || localPort > 0) - { - // we need to bind explicitly - if (localPort < 0) - { - localPort = 0; // indicates "any" - } - - local = new InetSocketAddress(localAddress, localPort); - } - - InetAddress remoteAddress; - - if (this.nameResolver != null) - { - remoteAddress = this.nameResolver.resolve(host); - } - else - { - remoteAddress = InetAddress.getByName(host); - } - - InetSocketAddress remote = new InetSocketAddress(remoteAddress, port); - - return connectSocket(socket, remote, local, params); - } - - /** - * @deprecated Use {@link #createLayeredSocket(Socket, String, int, boolean)} - */ - @Deprecated - public Socket createSocket(final Socket socket, final String host, int port, boolean autoClose) throws IOException - { - return createLayeredSocket(socket, host, port, autoClose); - } -} \ No newline at end of file diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/TrustManagerDecorator.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/TrustManagerDecorator.java deleted file mode 100644 index 6e593418..00000000 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/TrustManagerDecorator.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ -package org.moire.ultrasonic.service.ssl; - -import android.annotation.SuppressLint; - -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -import javax.net.ssl.X509TrustManager; - -/** - * @since 4.1 - */ -@SuppressLint("CustomX509TrustManager") -class TrustManagerDecorator implements X509TrustManager -{ - - private final X509TrustManager trustManager; - private final TrustStrategy trustStrategy; - - TrustManagerDecorator(final X509TrustManager trustManager, final TrustStrategy trustStrategy) - { - super(); - this.trustManager = trustManager; - this.trustStrategy = trustStrategy; - } - - @Override - public void checkClientTrusted(final X509Certificate[] chain, final String authType) throws CertificateException - { - this.trustManager.checkClientTrusted(chain, authType); - } - - @Override - public void checkServerTrusted(final X509Certificate[] chain, final String authType) throws CertificateException - { - if (!this.trustStrategy.isTrusted(chain, authType)) - { - this.trustManager.checkServerTrusted(chain, authType); - } - } - - @Override - public X509Certificate[] getAcceptedIssuers() - { - return this.trustManager.getAcceptedIssuers(); - } -} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/TrustSelfSignedStrategy.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/TrustSelfSignedStrategy.java deleted file mode 100644 index 1e09924c..00000000 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/TrustSelfSignedStrategy.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ -package org.moire.ultrasonic.service.ssl; - -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -/** - * A trust strategy that accepts self-signed certificates as trusted. Verification of all other - * certificates is done by the trust manager configured in the SSL context. - * - * @since 4.1 - */ -public class TrustSelfSignedStrategy implements TrustStrategy -{ - @Override - public boolean isTrusted(final X509Certificate[] chain, final String authType) throws CertificateException - { - return true; - } - -} diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/TrustStrategy.java b/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/TrustStrategy.java deleted file mode 100644 index 950588b9..00000000 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/service/ssl/TrustStrategy.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * ==================================================================== - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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. See the License for the - * specific language governing permissions and limitations - * under the License. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * . - * - */ -package org.moire.ultrasonic.service.ssl; - -import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; - -/** - * A strategy to establish trustworthiness of certificates without consulting the trust manager - * configured in the actual SSL context. This interface can be used to override the standard - * JSSE certificate verification process. - * - * @since 4.1 - */ -public interface TrustStrategy -{ - - /** - * Determines whether the certificate chain can be trusted without consulting the trust manager - * configured in the actual SSL context. This method can be used to override the standard JSSE - * certificate verification process. - *

- * Please note that, if this method returns false, the trust manager configured - * in the actual SSL context can still clear the certificate as trusted. - * - * @param chain the peer certificate chain - * @param authType the authentication type based on the client certificate - * @return true if the certificate can be trusted without verification by - * the trust manager, false otherwise. - * @throws CertificateException thrown if the certificate is not trusted or invalid. - */ - boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException; - -} diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt index 6206816e..ee625720 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/activity/NavigationActivity.kt @@ -22,6 +22,7 @@ import android.view.Menu import android.view.MenuItem import android.view.View import android.widget.ImageView +import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar import androidx.core.content.ContextCompat @@ -220,6 +221,8 @@ class NavigationActivity : AppCompatActivity() { cachedServerCount = count ?: 0 updateNavigationHeaderForServer() } + + onBackPressedDispatcher.addCallback(this, callback) } override fun onResume() { @@ -337,13 +340,16 @@ class NavigationActivity : AppCompatActivity() { setupActionBarWithNavController(navController, appBarConfig) } - override fun onBackPressed() { - if (drawerLayout?.isDrawerVisible(GravityCompat.START) == true) { - this.drawerLayout?.closeDrawer(GravityCompat.START) - } else { - val currentFragment = host!!.childFragmentManager.fragments.last() - if (currentFragment is OnBackPressedHandler) currentFragment.onBackPressed() - else super.onBackPressed() + val callback: OnBackPressedCallback = object : OnBackPressedCallback( + true + ) { + override fun handleOnBackPressed() { + if (drawerLayout?.isDrawerVisible(GravityCompat.START) == true) { + drawerLayout?.closeDrawer(GravityCompat.START) + } else { + val currentFragment = host!!.childFragmentManager.fragments.last() + if (currentFragment is OnBackPressedHandler) currentFragment.onBackPressed() + } } } diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt index 74e810c0..e1c32c2f 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/fragment/SettingsFragment.kt @@ -250,7 +250,8 @@ class SettingsFragment : val dialogFragment = TimeSpanPreferenceDialogFragmentCompat() val bundle = Bundle(1) bundle.putString("key", preference.getKey()) - dialogFragment.setArguments(bundle) + dialogFragment.arguments = bundle + @Suppress("DEPRECATION") // Their own super class uses this call :shrug: dialogFragment.setTargetFragment(this, 0) dialogFragment.show( this.parentFragmentManager, diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadTask.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadTask.kt index 45d7a9cd..a192f598 100644 --- a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadTask.kt +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/service/DownloadTask.kt @@ -110,10 +110,19 @@ class DownloadTask( // Manual throttling to avoid overloading Rx if (SystemClock.elapsedRealtime() - lastPostTime > REFRESH_INTERVAL) { lastPostTime = SystemClock.elapsedRealtime() + + // If the file size is unknown we can only provide null as the progress + val size = item.track.size ?: 0 + val progress = if (size <= 0) { + null + } else { + (totalBytesCopied * 100 / (size)).toInt() + } + stateChangedCallback( item, DownloadState.DOWNLOADING, - (totalBytesCopied * 100 / (item.track.size ?: 1)).toInt() + progress ) } } diff --git a/ultrasonic/src/main/res/layout/search.xml b/ultrasonic/src/main/res/layout/search.xml index 513054b2..87d5ab49 100644 --- a/ultrasonic/src/main/res/layout/search.xml +++ b/ultrasonic/src/main/res/layout/search.xml @@ -1,6 +1,5 @@