New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support enabling TLSv1.2 on Android 4.1-4.4. #2372

Closed
mlc opened this Issue Feb 25, 2016 · 43 comments

Comments

@mlc
Contributor

mlc commented Feb 25, 2016

Our lawyers and security consultants claim that for PCI compliance*, we must disable TLS 1.0 and 1.1 on our servers. For some confusing reason, Android has supported TLS 1.2 since API 16 (android 4.1) but enabled it by default only since API 20 (android "4.4W").

With okhttp 2.6, we were able to force use of TLS 1.2 with:

OkHttpClient cli = new OkHttpClient();
SSLContext sc = SSLContext.getInstance("TLSv1.2");
sc.init(null, null, null);
cli.setSslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));
ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
        .tlsVersions(TlsVersion.TLS_1_2)
        .build();
cli.setConnectionSpecs(ImmutableList.of(cs));

where Tls12SocketFactory is this.

However, okhttp 3.1 uses some kind of reflection on internal implementation details of the SSLSocketFactory, so the above implementation no longer works. And, indeed, it's a bit silly to make callers write so much code anyway. Specifying TLS_1_2 in the ConnectionSpec should be enough to get TLSv1.2 whenever it is supported.

As far as I can tell, the only reason why the custom socket factory is needed in the first place is that ConnectionSpec.supportedSpec() calls SSLSocket.getEnabledProtocols() to learn the list of protocols supported by the system, so on Android 4.x where TLS 1.2 is supported but not enabled by default, OkHttp thinks 1.2 is not supported at all.

Sorry for this long bug report: I think the fix is as simple as changing getEnabledProtocols() above to getSupportedProtocols() but wanted to submit this bug for discussion before making a PR with such a change, in case there is some affirmative reason why it's the other way now.

* Originally I understood the PCI compliance deadline to be June 2016; however, it seems like it has since been changed to be June 2018. Regardless, OkHttp should support this change for users that want it.

@swankjesse

This comment has been minimized.

Show comment
Hide comment
@swankjesse

swankjesse Feb 25, 2016

Member

As a quick fix, try renaming the SSLSocketFactory field in Tls12SocketFactory to delegate. It’s a gross hack, and it’s sad, and it’s how we cope with the absence of the APIs we need doing fancy TLS in Java.

Member

swankjesse commented Feb 25, 2016

As a quick fix, try renaming the SSLSocketFactory field in Tls12SocketFactory to delegate. It’s a gross hack, and it’s sad, and it’s how we cope with the absence of the APIs we need doing fancy TLS in Java.

@swankjesse

This comment has been minimized.

Show comment
Hide comment
@swankjesse

swankjesse Mar 20, 2016

Member

No action for us to take here.

Member

swankjesse commented Mar 20, 2016

No action for us to take here.

@swankjesse swankjesse closed this Mar 20, 2016

@gotev

This comment has been minimized.

Show comment
Hide comment
@gotev

gotev Sep 5, 2016

Had the same issue on Android < 5.0 (16 <= API < 20). Thanks to your posts, I was able to make this work, so for anyone who gets here, this is the out-of-the-box solution. At the time of this writing, I'm using OkHttp 3.4.1.

Edit:
I've done some tests and the same issue also happens on some Samsung devices with API 21. Solved by applying the solution also for API 21

Add Tls12SocketFactory.java with the following content:

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

/**
 * Enables TLS v1.2 when creating SSLSockets.
 * <p/>
 * For some reason, android supports TLS v1.2 from API 16, but enables it by
 * default only from API 20.
 * @link https://developer.android.com/reference/javax/net/ssl/SSLSocket.html
 * @see SSLSocketFactory
 */
public class Tls12SocketFactory extends SSLSocketFactory {
    private static final String[] TLS_V12_ONLY = {"TLSv1.2"};

    final SSLSocketFactory delegate;

    public Tls12SocketFactory(SSLSocketFactory base) {
        this.delegate = base;
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return delegate.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return delegate.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return patch(delegate.createSocket(s, host, port, autoClose));
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return patch(delegate.createSocket(host, port));
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return patch(delegate.createSocket(host, port, localHost, localPort));
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        return patch(delegate.createSocket(host, port));
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        return patch(delegate.createSocket(address, port, localAddress, localPort));
    }

    private Socket patch(Socket s) {
        if (s instanceof SSLSocket) {
            ((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY);
        }
        return s;
    }
}

Then, add this method somewhere in your code:

public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
    if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
        try {
            SSLContext sc = SSLContext.getInstance("TLSv1.2");
            sc.init(null, null, null);
            client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));

            ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                    .tlsVersions(TlsVersion.TLS_1_2)
                    .build();

            List<ConnectionSpec> specs = new ArrayList<>();
            specs.add(cs);
            specs.add(ConnectionSpec.COMPATIBLE_TLS);
            specs.add(ConnectionSpec.CLEARTEXT);

            client.connectionSpecs(specs);
        } catch (Exception exc) {
            Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc);
        }
    }

    return client;
}

And when you create your OkHttp instance, use it for example like this:

private OkHttpClient getNewHttpClient() {
    OkHttpClient.Builder client = new OkHttpClient.Builder()
            .followRedirects(true)
            .followSslRedirects(true)
            .retryOnConnectionFailure(true)
            .cache(null)
            .connectTimeout(5, TimeUnit.SECONDS)
            .writeTimeout(5, TimeUnit.SECONDS)
            .readTimeout(5, TimeUnit.SECONDS);

    return enableTls12OnPreLollipop(client).build();
}

Also, be sure to use well known CAs for your server side certificates when targeting older Androids.

Credits to @StuStirling and @techiebrij:

To check your server side certificates:
https://developer.android.com/reference/javax/net/ssl/SSLEngine.html

Or:
https://gist.github.com/gotev/f1a8a221e2d1d09bcb93e823b8e5a05a

For anyone else that may be struggling with this, the thing that fixed mine was to install the latest security fixes that are bundled with Google Play Services.

ProviderInstaller.installIfNeeded(context);

After doing this, the solution for enabling TLS1.2 worked.

gotev commented Sep 5, 2016

Had the same issue on Android < 5.0 (16 <= API < 20). Thanks to your posts, I was able to make this work, so for anyone who gets here, this is the out-of-the-box solution. At the time of this writing, I'm using OkHttp 3.4.1.

Edit:
I've done some tests and the same issue also happens on some Samsung devices with API 21. Solved by applying the solution also for API 21

Add Tls12SocketFactory.java with the following content:

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

/**
 * Enables TLS v1.2 when creating SSLSockets.
 * <p/>
 * For some reason, android supports TLS v1.2 from API 16, but enables it by
 * default only from API 20.
 * @link https://developer.android.com/reference/javax/net/ssl/SSLSocket.html
 * @see SSLSocketFactory
 */
public class Tls12SocketFactory extends SSLSocketFactory {
    private static final String[] TLS_V12_ONLY = {"TLSv1.2"};

    final SSLSocketFactory delegate;

    public Tls12SocketFactory(SSLSocketFactory base) {
        this.delegate = base;
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return delegate.getDefaultCipherSuites();
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return delegate.getSupportedCipherSuites();
    }

    @Override
    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
        return patch(delegate.createSocket(s, host, port, autoClose));
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return patch(delegate.createSocket(host, port));
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {
        return patch(delegate.createSocket(host, port, localHost, localPort));
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        return patch(delegate.createSocket(host, port));
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        return patch(delegate.createSocket(address, port, localAddress, localPort));
    }

    private Socket patch(Socket s) {
        if (s instanceof SSLSocket) {
            ((SSLSocket) s).setEnabledProtocols(TLS_V12_ONLY);
        }
        return s;
    }
}

Then, add this method somewhere in your code:

public static OkHttpClient.Builder enableTls12OnPreLollipop(OkHttpClient.Builder client) {
    if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 22) {
        try {
            SSLContext sc = SSLContext.getInstance("TLSv1.2");
            sc.init(null, null, null);
            client.sslSocketFactory(new Tls12SocketFactory(sc.getSocketFactory()));

            ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                    .tlsVersions(TlsVersion.TLS_1_2)
                    .build();

            List<ConnectionSpec> specs = new ArrayList<>();
            specs.add(cs);
            specs.add(ConnectionSpec.COMPATIBLE_TLS);
            specs.add(ConnectionSpec.CLEARTEXT);

            client.connectionSpecs(specs);
        } catch (Exception exc) {
            Log.e("OkHttpTLSCompat", "Error while setting TLS 1.2", exc);
        }
    }

    return client;
}

And when you create your OkHttp instance, use it for example like this:

private OkHttpClient getNewHttpClient() {
    OkHttpClient.Builder client = new OkHttpClient.Builder()
            .followRedirects(true)
            .followSslRedirects(true)
            .retryOnConnectionFailure(true)
            .cache(null)
            .connectTimeout(5, TimeUnit.SECONDS)
            .writeTimeout(5, TimeUnit.SECONDS)
            .readTimeout(5, TimeUnit.SECONDS);

    return enableTls12OnPreLollipop(client).build();
}

Also, be sure to use well known CAs for your server side certificates when targeting older Androids.

Credits to @StuStirling and @techiebrij:

To check your server side certificates:
https://developer.android.com/reference/javax/net/ssl/SSLEngine.html

Or:
https://gist.github.com/gotev/f1a8a221e2d1d09bcb93e823b8e5a05a

For anyone else that may be struggling with this, the thing that fixed mine was to install the latest security fixes that are bundled with Google Play Services.

ProviderInstaller.installIfNeeded(context);

After doing this, the solution for enabling TLS1.2 worked.

@meyn

This comment has been minimized.

Show comment
Hide comment
@meyn

meyn Nov 17, 2016

@gotev thanks for sharing, any particular reason you've added the COMPATIBLE_TLS and CLEARTEXT in your connection specs? aren't these necessary only if you want to allow fallbacks to older TLS versions / cleartext http?

meyn commented Nov 17, 2016

@gotev thanks for sharing, any particular reason you've added the COMPATIBLE_TLS and CLEARTEXT in your connection specs? aren't these necessary only if you want to allow fallbacks to older TLS versions / cleartext http?

@gotev

This comment has been minimized.

Show comment
Hide comment
@gotev

gotev Nov 17, 2016

It's like that to be as generic as possibile. You could always remove them from the client if you only use TLS 1.2

gotev commented Nov 17, 2016

It's like that to be as generic as possibile. You could always remove them from the client if you only use TLS 1.2

@yoavgrosswild

This comment has been minimized.

Show comment
Hide comment
@yoavgrosswild

yoavgrosswild Feb 6, 2017

Seems like client.sslSocketFactory(sslSocketFactory) is deprecated and the documentation recommends using client.sslSocketFactory(sslSocketFactory, X509TrustManager trustManager). How do i get an X509TrustManager object? just create new ?

yoavgrosswild commented Feb 6, 2017

Seems like client.sslSocketFactory(sslSocketFactory) is deprecated and the documentation recommends using client.sslSocketFactory(sslSocketFactory, X509TrustManager trustManager). How do i get an X509TrustManager object? just create new ?

@cantek41

This comment has been minimized.

Show comment
Hide comment
@cantek41

cantek41 Apr 2, 2017

SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
TrustManager[] trustManagers = new TrustManager[] { new TrustManagerManipulator() };
sslContext.init(null, trustManagers, new SecureRandom());
SSLSocketFactory noSSLv3Factory = new TLSSocketFactory(sslContext.getSocketFactory());
urlConnection.setSSLSocketFactory(noSSLv3Factory);

https://github.com/IKANOW/Infinit.e/blob/master/core/infinit.e.data_model/src/com/ikanow/infinit/e/data_model/utils/TrustManagerManipulator.java

cantek41 commented Apr 2, 2017

SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
TrustManager[] trustManagers = new TrustManager[] { new TrustManagerManipulator() };
sslContext.init(null, trustManagers, new SecureRandom());
SSLSocketFactory noSSLv3Factory = new TLSSocketFactory(sslContext.getSocketFactory());
urlConnection.setSSLSocketFactory(noSSLv3Factory);

https://github.com/IKANOW/Infinit.e/blob/master/core/infinit.e.data_model/src/com/ikanow/infinit/e/data_model/utils/TrustManagerManipulator.java

@aquakul

This comment has been minimized.

Show comment
Hide comment
@aquakul

aquakul Apr 10, 2017

Slightly unrelated. But once I make the changes, how do I actually confirm that app and server are indeed using TLS 1.2 (on my server TLS 1.0, 1.1 and 1.2 all are enabled). Is there a hint in the HTTP packet ?

aquakul commented Apr 10, 2017

Slightly unrelated. But once I make the changes, how do I actually confirm that app and server are indeed using TLS 1.2 (on my server TLS 1.0, 1.1 and 1.2 all are enabled). Is there a hint in the HTTP packet ?

@swankjesse

This comment has been minimized.

Show comment
Hide comment
@swankjesse

swankjesse Apr 10, 2017

Member

Check the Handshake object on the Response.

Member

swankjesse commented Apr 10, 2017

Check the Handshake object on the Response.

@thuytrinh

This comment has been minimized.

Show comment
Hide comment
@thuytrinh

thuytrinh Mar 22, 2018

The patch in #2372 (comment) actually worked for us.

thuytrinh commented Mar 22, 2018

The patch in #2372 (comment) actually worked for us.

@moz1q1

This comment has been minimized.

Show comment
Hide comment
@moz1q1

moz1q1 commented May 7, 2018

i see

miankhalid added a commit to edx/edx-app-android that referenced this issue May 25, 2018

Add TLS 1.2 protocol support for Pre-Lollipop Devices
- LEARNER-5406
TLS 1.2 isn't by default enabled on Pre-Lollipop Devices which is the
protocol that our backend has updated to. This commit enables it so that
server-client communication is seamless.

Inspiration for this fix:
square/okhttp#2372 (comment)

miankhalid added a commit to edx/edx-app-android that referenced this issue May 28, 2018

Add TLS 1.2 protocol support for Pre-Lollipop Devices
- LEARNER-5406
TLS 1.2 isn't by default enabled on Pre-Lollipop Devices which is the
protocol that our backend has updated to. This commit enables it so that
server-client communication is seamless.

Inspiration for this fix:
square/okhttp#2372 (comment)
@lucaskuan

This comment has been minimized.

Show comment
Hide comment
@lucaskuan

lucaskuan Jul 1, 2018

For those who still getting SSL handshake error even with the fix provided by @gotev. I suggested to use the correct cipher suite that your webserver support and specify it in the ConnectionSpec builder.
e.g.

// written in Kotlin
val cs = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                    .tlsVersions(TlsVersion.TLS_1_2)
                    .cipherSuites(
                            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
                            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
                    .build()

You can check your ssl details here https://www.ssllabs.com/ssltest/

lucaskuan commented Jul 1, 2018

For those who still getting SSL handshake error even with the fix provided by @gotev. I suggested to use the correct cipher suite that your webserver support and specify it in the ConnectionSpec builder.
e.g.

// written in Kotlin
val cs = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
                    .tlsVersions(TlsVersion.TLS_1_2)
                    .cipherSuites(
                            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
                            CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA)
                    .build()

You can check your ssl details here https://www.ssllabs.com/ssltest/

@Zo2m4bie

This comment has been minimized.

Show comment
Hide comment
@Zo2m4bie

Zo2m4bie Jul 7, 2018

Hello. I tried solution provided by @gotev and @lucaskuan
I tested TLS on
https://api.fastly.com/public-ip-list
https://tlstest.paypal.com/
However on my website I still receive error

javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb950bc70: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x9c8367f1:0x00000000)

My urls works fine on android 5. I found clipper on my api use the same clipper as tested ones TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 So it should work but it's not.
Does anyone know what can be the reason?

Zo2m4bie commented Jul 7, 2018

Hello. I tried solution provided by @gotev and @lucaskuan
I tested TLS on
https://api.fastly.com/public-ip-list
https://tlstest.paypal.com/
However on my website I still receive error

javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0xb950bc70: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:744 0x9c8367f1:0x00000000)

My urls works fine on android 5. I found clipper on my api use the same clipper as tested ones TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 So it should work but it's not.
Does anyone know what can be the reason?

@lucaskuan

This comment has been minimized.

Show comment
Hide comment
@lucaskuan

lucaskuan Jul 7, 2018

@Zo2m4bie I have the same issue too. Because according to this file.
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 cipher suite is not supported by Android 4.4 and Java 7 😞
So looks like we should use this fix suggested here

lucaskuan commented Jul 7, 2018

@Zo2m4bie I have the same issue too. Because according to this file.
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 cipher suite is not supported by Android 4.4 and Java 7 😞
So looks like we should use this fix suggested here

@Zo2m4bie

This comment has been minimized.

Show comment
Hide comment
@Zo2m4bie

Zo2m4bie Jul 7, 2018

@lucaskuan
But I can't understand how these work:
https://api.fastly.com/public-ip-list
https://tlstest.paypal.com/
They use TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 too

Zo2m4bie commented Jul 7, 2018

@lucaskuan
But I can't understand how these work:
https://api.fastly.com/public-ip-list
https://tlstest.paypal.com/
They use TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 too

@KeyStarr

This comment has been minimized.

Show comment
Hide comment
@KeyStarr

KeyStarr Jul 11, 2018

I was facing that very same issue while using Glide. I tried to combine solutions from this discussions and some others, but was unsuccessfull.
However i found a working solution for enabling TSL v1.2 for okhttp 3 with glide, here it is (as i see also based on thought from this thread):
https://developer.android.com/reference/javax/net/ssl/SSLSocket

I am not sure whether my comment is appropriate since it is an okhttp rep, but despite glide references one can still extract a working okhttp-only solution.

KeyStarr commented Jul 11, 2018

I was facing that very same issue while using Glide. I tried to combine solutions from this discussions and some others, but was unsuccessfull.
However i found a working solution for enabling TSL v1.2 for okhttp 3 with glide, here it is (as i see also based on thought from this thread):
https://developer.android.com/reference/javax/net/ssl/SSLSocket

I am not sure whether my comment is appropriate since it is an okhttp rep, but despite glide references one can still extract a working okhttp-only solution.

ahmad-hsn added a commit to ahmad-hsn/edx-app-android that referenced this issue Jul 11, 2018

Add TLS 1.2 protocol support for Pre-Lollipop Devices
- LEARNER-5406
TLS 1.2 isn't by default enabled on Pre-Lollipop Devices which is the
protocol that our backend has updated to. This commit enables it so that
server-client communication is seamless.

Inspiration for this fix:
square/okhttp#2372 (comment)

joerg04 pushed a commit to joerg04/webtrekk-android-sdk that referenced this issue Aug 2, 2018

ahmad-hsn added a commit to ahmad-hsn/edx-app-android that referenced this issue Aug 6, 2018

Add TLS 1.2 protocol support for Pre-Lollipop Devices
- LEARNER-5406
TLS 1.2 isn't by default enabled on Pre-Lollipop Devices which is the
protocol that our backend has updated to. This commit enables it so that
server-client communication is seamless.

Inspiration for this fix:
square/okhttp#2372 (comment)

joerg04 added a commit to joerg04/webtrekk-android-sdk that referenced this issue Aug 14, 2018

Add an option to enable TLSv1.2 on some Android versions.
Devices have to support TLSv1.2 from API level 16 (Jelly Bean) on,
but it's not enabled per default till API level 21 (Lollipop) [1,2].

To use this option on such devices, add the following line after
 "Webtrekk.init(..)":

  Webtrekk.setTls12Enabled(true);

[1] https://developer.android.com/reference/javax/net/ssl/SSLContext
[2] square/okhttp#2372

joerg04 added a commit to joerg04/webtrekk-android-sdk that referenced this issue Aug 14, 2018

Add an option to enable TLSv1.2 on some Android versions.
Devices have to support TLSv1.2 from API level 16 (Jelly Bean) on,
but it's not enabled per default till API level 21 (Lollipop) [1,2].

To use this option on such devices, add the following line before
initialization of class "Webtrekk":

  Webtrekk.setTls12Enabled(true);
  Webtrekk.getInstance().initWebtrekk(..);

[1] https://developer.android.com/reference/javax/net/ssl/SSLContext
[2] square/okhttp#2372

joerg04 added a commit to joerg04/webtrekk-android-sdk that referenced this issue Aug 15, 2018

Add an option to enable TLSv1.2 on some Android versions.
Devices have to support TLSv1.2 from API level 16 (Jelly Bean) on,
but it's not enabled per default till API level 21 (Lollipop) [1,2].

To use this option on such devices, add the following line before
initialization of class "Webtrekk":

  Webtrekk.setTls12Enabled(true);
  Webtrekk.getInstance().initWebtrekk(..);

[1] https://developer.android.com/reference/javax/net/ssl/SSLContext
[2] square/okhttp#2372

MBing added a commit to Webtrekk/webtrekk-android-sdk that referenced this issue Aug 15, 2018

Add an option to enable TLSv1.2 on some Android versions. (#23)
Devices have to support TLSv1.2 from API level 16 (Jelly Bean) on,
but it's not enabled per default till API level 21 (Lollipop) [1,2].

To use this option on such devices, add the following line before
initialization of class "Webtrekk":

  Webtrekk.setTls12Enabled(true);
  Webtrekk.getInstance().initWebtrekk(..);

[1] https://developer.android.com/reference/javax/net/ssl/SSLContext
[2] square/okhttp#2372
@skauss

This comment has been minimized.

Show comment
Hide comment
@skauss

skauss Aug 24, 2018

@gotev Thank you for your example

skauss commented Aug 24, 2018

@gotev Thank you for your example

scana added a commit to filestack/filestack-java that referenced this issue Sep 27, 2018

Enable TLS 1.2 support for pre-KitKat Android devices
-- this change is required in order to make network requests work on pre Kitkat devices
-- take a look here: square/okhttp#2372

scana added a commit to filestack/filestack-java that referenced this issue Sep 27, 2018

Enable TLS 1.2 support for pre-KitKat Android devices (#79)
-- this change is required in order to make network requests work on pre Kitkat devices
-- take a look here: square/okhttp#2372

kearabiloe added a commit to kearabiloe/edx-app-android that referenced this issue Oct 10, 2018

Update Fork (#1)
* Upgrade Crashlytics

* Apply activity visiblity check before showing dialog

- LEARNER-1988

* Improvements to delete videos by long press

- LEARNER-1288
- SnackBar's visibility time increased to 5000 milliseconds
- Allow whole row long tap if its downloaded i.e. make downloaded state
icon non-clickable
- Fix crash where SnackBar's dismiss callback gets called twice when it
is about to dismiss and the activity finishes

* Change Content-Type of create comment/response API

- LEARNER-2734
- Changes done to support the Content-Type: application/json instead of
the previously used application/x-www-form-urlencoded type

* keep some files common for iOS and android on transifex

- Files are profiles.json, languages.json and countries.json
- Removed whats_new.json from transifex

* Add support of Spanish language

- LEARNER-2360

* Show correct error message while adding something on closed posts

* Show due date in course subsection

- LEARNER-301

* Push files to transifex only from master

* Push files to transifex only from master

* Revert changes of PR #998 which was just for testing purpose

* Fix transcript's first line skipping

- LEARNER-242
We are using subtitleConvert library's FormatSRT class to parse our
transcript files which by default expects the index of captions within
the file to be starting from 1.
Our transcript files start their captions' index from 0, so, the library
has been modified and the jar updated to support our captions properly.
Previously due to the index issue, we were skipping the first caption in
our transcript files.
Library's GitHub link: https://github.com/JDaren/subtitleConverter

* Apply correct attribute for missing translations

- LEARNER-2492

The attribute tools:ignore="MissingTranslation" should be used for any
new string that we add in our project from now on.

* Change videos download icon

- LEARNER-2524
- Download icon change from fa_arrow_down to fa_download.

* Fixed time zone calculation and ui ripples produced in due date story

- LEARNER-301
- Revert the 2 character format time zone calculation (which are
actually the country codes), we are only using android api time zone
functions for now.
- Fixed course outline list items varied height issue.
- Fixed wrong boldness on video duration text issue.

* Analytics for Course Videos feature

- LEARNER-2156

* Combine 'My Courses' and 'Find Courses' experiences

- LEARNER-2036

* Introduce Account area in app

- LEARNER-2037
- Account button introduced on the Navigation drawer.
- My Settings, Submit Feedback and Logout buttons removed from
Navigation drawer and moved to Account screen.
- App version text also move to Account screen.
- User email removed from drawer.

* Fix issue of wrong full screen spinner appear on video downloading

- LEARNER-2636

* Show video size and duration on a video component.

- LEARNER-2417

* Update README of project

- Changed format from .rst to .md
- Add FAQ item to help the community about issues faced while
upgrading to Android Studio v2.3.x
- Add Flavors section
- Add Build Variants section
- Add FAQ item for Firebase related issue
- Formatting changes

* Show proper error messages in Find Courses

- LEARNER-2578
- Modern design for showing error text with image on top.
- Different logic for showing error on pre-Marshmallow devices by first
hitting the url before loading it in WebView.
- Errors are now shown based on the scenario when and where the issue
occurs.
- Standardize loading of find courses links on all platforms whether it
be all courses, course search or a course's detail.
- Refactored WebView URL loading into WebViewUtil class.

* Consistent design on web-based Find Courses detail screen

* Makes a single What's New messages file for both platforms

- LEARNER-2526

* Release 2.11.0

- Add WhatsNew assets
- Add WhatsNew json files (English and Spanish)
- Spanish strings for initial Spanish support in app

* Discussion Threads screen fixes

- LEARNER-1446
- Fix crash in case of offline inline discussion view
- New error design with text and icon

* Branch Integration

- LEARNER-2627
- Feature flag for Branch integration is placed under Fabric -> Kits in
the Config.java file
- Deep links work even when Branch is disabled in config (the only catch
is that the hits are never reported on the dashboard)
- Course Dashboard Test fix

* Remove duration from downloading screen if have zero value

- LEARNER-2767
- Rewrite xml of row_download_list for code optimization.
- Add ripple on on cancel download button and increase its touch area.

* Implement Answers and add Enrollment &  Registration success events

- LEARNER-2629
- Also implement Enrollment and Registration success events for Firebase and Segement

* Remove My Videos feature code

- LEARNER-2740
- Delete related unused resources
- Remove MY_VIDEOS feature flag
- Remove restore-cache task related to My Videos feature
- Remove MyVideos test suite

* Enable Course Videos feature by-default

* Ignore NewApi lint check (temporarily) due to Travis issue

More details about the Travis issue can be found here:
travis-ci/travis-ci#8676

* Update course dates web fragment link.

- LEARNER-2923
- Refactor some code

* Implement Tab Layout for Course Dashboard

- LEARNER-2938

* Course Card and Last Accesed bar on Outline view

- LEARNER-2939
- Move all course outline logic from activities to fragment. Logic
from CourseBaseActivity and CourseVideoListActivity has been
refactored to the new fragment
- The fragment is now responsible for making the the required server
calls, handle offline and other errors and manage downloads
- Course card and Last accessed view now  appear within the listView
- Last accessed view is added to the listView asynchronously when the
server call finishes fetching the last accessed course item
- Last accessed view has been modified to meet the new design's style
- Course item's left padding matched  with that of Last accessed item
- Hide listview initially. It'll become visible once server call is
done and we have course data ready to populate it
- Add NewCourseOutlineFragment for Course and Videos under their tabs

* Block drawer from opening on tabs dashboard screen

* Change a11y content for Search edit field in Discover Courses screen

- LEARNER-2917

* Remove autofocus from email field on Registration screen

- LEARNER-2913
- Also includes a workaround to fix auto announcement of Spinner's
accessibility text

* Fix hang issue

- LEARNER-3176
- SplashActivity wasn't getting finished when branch was disabled
causing this issue.

* Fix the typo exist in signing method names.

- LEARNER-3396

* Customize a11y behavior for registration screen fields.

- LEARNER-2916
- Fix number of issue to make a rational a11y behavior.

* LEARNER-3077

- Support HLS videos to stream with .m3u8 extension.
- Introduced the supported video formats. Only supported video formats will be stream in app media player now.

* Offline Mode for Tabs based Course Dashboard

- LEARNER-3060
- Ensure no 2 error types appear on screen at a time
- SnackBar showing/hiding will be controlled by the activity now, since,
its the activity's layout that contains the CoordinatorLayout in which
the SnackBar will appear.
- Fragments inside ViewPager will tell the Activity about showing/hiding
SnackBar based on the visibility of FullScreenError within them.
- Whenever Reload button will be pressed (whether its pressed on
SnackBar or FullScreenError) it'll fire a RefreshEvent on EventBus, so
that every fragment can update/reload itself.
- Offline Mode for AdditionalResources and CourseDates Fragment
- On AdditionalResourcesFragment we only need to show SnackBar in case
of no connectivity.
- Hide Snackbar on tab switch when network is available

* Rename ‘Additional Resources’ title to ‘Resources’

- LEARNER-3580
- Also refactored class names and xml file.

* Fix wrong a11y focus issue existed on registration screen.

- LEARNER-3656

* Dont consider cancelling of a server call as error

- LEARNER-3657
- Upon cancelling a server call, our error handling callback's onError
function was getting called, which shouldn't be considered as error.
- Also hiding the error explicitly when data is loaded on screen.

* Release 2.12

- Update whatsnew.json
- Update whatsnew screens
- Update strings

* Show Done button when only 1 whats new item is available

- LEARNER-3620

* Update ‘Important Dates’ tab title to ‘Dates’

- LEARNER-3333

* Add certificate in Course Outline tab of Course tabs dashboard. (#1046)

* Add certificate in Course Outline tab of Course tabs dashboard.

- LEARNER-3104

* Implement a new design of a toolbar having profile icon as home button.

- LEARNER-3582
- Put hamburger menu desing behind TAB_LAYOUTS_ENABLED feature flag.
- Implement the custom toolbar layout to show profile icon as a home button.

* Revert "Update ‘Important Dates’ tab title to ‘Dates’"

This reverts commit d7b7f9f.

* Tabs based design for app's main dashboard

- LEARNER-3251
- Fragment based implementation for Course Discovery
- Offline support for Courses and Discover fragments
- Base Fragment defined for Tabs based implmentations
to extend. Giving the inheriting classes easy to use
APIs for making use of Tabs with ViewPager
- Move offline support logic to base activity/fragment

* Fix for ViewPager's onPageSelected not getting called for its 1st item

ViewPager doesn't call the onPageSelected for its first item, so we have
to explicitly call it ourselves.

Solution Inspiration: https://stackoverflow.com/a/16074152/1402616

* Connect implementation of LEARNER-3582 with LEARNER-3251

JIRA link of both tickets:
- https://openedx.atlassian.net/browse/LEARNER-3582
- https://openedx.atlassian.net/browse/LEARNER-3251

* Removed some un-necessary checks.

- LEARNER-3251

* Fix buildSrc issue whose link is given below

- edx#1047

* Fix 'onRevisit' callback calls wrongly issue.

- LEARNER-3953

* Migrate to ToolBar in whole app

- LEARNER-3750
- Remove usages of ActionBar throughout the app
- AppBarLayout made parent of the toolbar layouts in app
- Themes and layouts updated for all the legacy activities that were
using ActionBar

Note: activity_login.xml is still a mess and needs some major cleanup,
some of the bigger issues have been resolved but total overhaul is
out of scope for this commit.

* Migrate ActionBar styles to ToolBar

* Set proper font of all TextViews on ToolBar

Calligraphy currently doesn't support setting of font through styles for
ToolBar due to which this hack is necessary.

Link to the relevant issue on the Calligraphy's GitHub page:
chrisjenx/Calligraphy#295

* Apply ToolBar properly in BaseSingleFragmentActivity

- Instead of placing the toolbar instead a FrameLayout ToolBar needs to
replace the placeholder view, so that the AppBarLayout can show the
bottom shadow properly.
- Bonus: File Autoformatted

* New color scheme for ToolBar and all the related elements on it

* Move Tabs to ToolBar from Fragment's layout

* Fix ToolBar shadow appearing after a delay

This fix is for a known issue in the support library due to which the
shadow beneath the AppBarLayout appears after a noticeable delay.

Link to issue: https://issuetracker.google.com/issues/37106543
Fix inspiration: https://stackoverflow.com/a/41137710/1402616

* Toolbar shadow for pre-lollipop devices

AppBarLayout on pre-lollipop devices doesn't add a shadow at its bottom.
To work around it, a shadow view explicitly needs to be added.

* Simplify and improve course outline data caching

- LEARNER-3841
- Here are the details of new caching mechanism:

Whenever course outline screen is loaded:
1) Firstly check if course data is available in app session cache (Lru Cache), if its available just load the data.
2) If course data is not available in app session check if its available in retrofit cache, if its available load the data. Moreover if course outline is loading first time in the app session then send the server call in background for updated data. Course outline will be refreshed on server response.
3) In step 2 if course data is not available in retrofit cache then send the server call to get the course data first time in app.
4) In new tabs dashboard, 1 hour retrofit caching time should be removed, so that retrofit bring the latest response from server whenever required.

* Ensure proper look and feel on all screens

- New design for User Profile screen
- Remove extra LinearLayout from all CoordinatorLayouts
- Standardize toolbar colors
- Fix hamburger color
- Add fitsSystemWindows to CoordinatorLayout
- ColorStateList application fix for Tabs
- Revert activity_course_base to use LinearLayout as parent
under CoordinatorLayout

* Added all missing ids of views for logistration screen.

* Focus search bar on selection of discovery tab.

- LEARNER-4169

* Check validity of context before loading the image via Glide lib.

- LEARNER-3186

* Find downloadable url from ‘all_sources’ if video pipeline is disabled.

- LEARNER-3743
- In case 'USING_VIDEO_PIPELINE' feature flag is disabled and we have
HLS encoding format in a video, we are trying to find some downloadable
url from 'all_sources' urls coming from server.

* Fixed a bug. Reverting the check to make it working properly.

- It was created in following PR
edx@795556b#r27504119

* Move initialization of SearchView from onAttach to onActivityCreated

- LEARNER-4206
Having the initialization code in onAttach causes the app to crash
whenever the fragment/activity has to be recreated for whatever reason.
onActivityCreated is also the logically correct home for this code as
activity creating is the prerequisite for the SearchView to be
initialized.

* Deprecate old dashboards and hamburger menu design related code.

- LEARNER-4141
- Deprecate MyCoursesListActivity, CourseDashboardActivity,
NavigationFragment and other classes.

* Handle the case where server sends non-parsable course content

- LEARNER-3785
Previously our app used to crash whenever the server returned a course
whose content was invalid and logged an exception on Crashlytics. This
commit gracefully handles that exception by wrapping it into
CourseContentNotValidException and showing an error on screen while
sending the exception to Crashlytics in the background too.

CourseContentNotValidException is either thrown when raised during a
test's execution or caught and re-thrown again as a RuntimeException as
it was being done for some other cases as well.

* Change Courses and Course Discovery screen course card layout.

- LEARNER-3741

* Fix app crash occurs during navigation in course outline screen.

- LEARNER-4629
- This issue was produced in the following PR. Now its not necessary
that we always get course data in server call, so its better to set
courseComponentId in loadData function.
https://github.com/edx/edx-app-android/pull/1055/commits

* Add Bulk Videos Download feature

- LEARNER-2940
- Add ConstraintLayout and use it for building the bulk videos download
view
Database is queried for all the data that it has for a course's videos
and then they are cross matched with the videos data of the same course
that we get from the server call to decide:
1 - How many videos have been downloaded
2 - How many videos can be downloaded
3 - How many videos are currently being downloaded

Two lists are kept for the implementation to work.
- 1st list keeps all the remaining videos that can be downloaded.
- 2nd list keeps all the videos that have been downloaded or the ones
that are currently being downloaded.
When the switch is ON, all videos in the 1st list are downloaded.
When the switch is OFF, all videos in the 2nd list are deleted (if
downloaded) and stopped (if downloading) after a delay.

When all videos are in progress, tapping the bulk download view takes
user to the Download Videos screen.

- Helpers for getting progress of downloading videos in a course
Functions added in various classes to obtain the videos that are
being downloaded by the DownloadManager, filtering them on the
basis of Course ID.
If Course ID isn't provided, unfiltered videos being downloaded
are returned.
- Only show download progress menu item on Course Tab
- Hide bulk download view if a course has NO downloadable videos
- Add accessibility to bulk download view
- Put all business logic in AsyncTask for DownloadCompleteReceiver
The code inside receiver was previously being run on the main thread
and didn't involve any interaction with the UI elements causing lag
within the app.

Introduce fragment for Bulk Download View

- BulkDownloadFragment is responsible for handling all the various
states of the bulk download view.
- Switch's state is saved in the prefs based on the course that its
being set in.
- Whenever a video is deleted, the bulk download switch's state for the
course whose video is deleted gets reset in the prefs.
- Disable BulkDownload while videos are being queued by DownloadManager
to download
- Update the download state of ListView rows whenever a download is
initiated even on a different tab
- Hide progress on BulkDownload view whenever a video is deleted or
an ongoing video download is stopped
- Spinner on Downloads screen before ListView is populated
- Update switch's state when it is OFF and all videos are individually
enqueued for downloading
- Commulative progress instead of the one download manager gives us
- Standardize the download limit check to DownloadUtil class's
isDownloadSizeWithinLimit function

Accessibility Improvements
- "Bulk videos download switch" added as a prefix before adding title,
subtitle etc to switch's contentDescription.
- While the switch is in ON state the whole view is now tappable to
during accessibility to open the Downloads screen. Matching string as
iOS in this case has also been added.

* Travis: Add local androidSDK license files and copy them to Travis

Reference:
wolkenschieber/License@3d3206c

* Release 2.13

- Update whatsnew.json
- Update whatsnew screens
- Update string resources

* Update Spanish version of whats_new file

Add missing translations for message keys for all items in v2.13

* LEARNER-4802

- Add debug logs to figure out the crash.

* Remove unused code related to Explore Subjects

- LEARNER-4469
- Unused code deleted and tests updated

* Fix Course Tabs Dashboard reloading on low memory

- LEARNER-4807
LruCache is purged when the system is low on memory due to which our
NewCourseOutlineFragment was throwing NPEs whenever it queried the
LruCache.

* Add new app landing screen

- Update DiscoveryLaunchActivity and its structure
- Add missing IDs
- Update screenshots for screenshot test cases
- Add analytics

* Update HTML Component icon

- LEARNER-4789

* Trigger Answer events for Login and Course Share

- LEARNER-4262

* Update crashlytics

- LEARNER-1305

* Fix course URL being sent to share event

Previously we were sending the whole share text in the url param for
course share event.

* Update share event for Answers

* Add LMS user ID to traits sent to Segment.io

- LEARNER-4443

* Use HLS video encoding and give it a top priority to stream.

- LEARNER-4757
- Add another column of ‘URL_HLS’ in database to persist HLS video
encoding in database.
- We need to persist 'URL_HLS' in database because in 'CourseUnitVideoFragment'
class we use 'DownloadEntry' db model object to choose prefered video at run
time, ref: https://github.com/edx/edx-app-android/blob/4e78d15cf31cd85dad2a85d78bd71bb3611ba7d3/OpenEdXMobile/src/main/java/org/edx/mobile/view/CourseUnitVideoFragment.java#L273.

* Add Bulk Download feature on Subsection view

- LEARNER-4160
- BulkDownloadFragment now accepts list of videos that need to be
downloaded in bulk and maintains its state accordingly.
- Database layer has been updated to give back videos based on video ids
provided to it.
- Fixed a case when 0.00 B was being shown on Bulk Download view.
- Use downloadable VideoInfo whenever a download needs to happen
- Handle the case when all the videos have been downloaded or they
are currently downloading without the use of Bulk Download switch.

* Stop showing download progress while deletion

Fixes LEARNER-4840. If the progress isn't stopped while the deletion is
happening, we are essentially querying the database for data that
might or might not be there causing exceptions to be thrown.

* Handle download cancelling from outside the app

A download can be cancelled from outside the apps as well using the
Downloads app or the cancel button on the download notification. This
commit handles the case when download is cancelled from outside the app.

* Switch from PULSE animation to SPIN

Animation.PULSE causes lag when a spinner stays on screen for a while.
Will be fixed in LEARNER-5053.

* Make HttpStatusException more meaningful

- LEARNER-2489
By the calling the Exception class's constructor requiring a String arg
with the response provided to HttpStatusException, we are essentially
making the exception object more meaningful with the Http call's
response details.

* Add new license implementation on Login and Register screen

- LEARNER-4959
- Add new license docs in HTML form
Parts of the license text have been made clickable by applying UrlSpans
on them. The URI attached to each link within the text is a custom made
URI that is broadcasted upon a link's click and received by one of our
activity (WebViewActivity) using an intent filter defined in
AndroidManifest.xml for the said activity.

* Remove all the deprecated code of old dashboard and hamburger menu.

- LEARNER-4143
- Rename NewCourseOutlineAdapter class to CourseOutlineAdapter.
- Rename NewCourseOutlineFragment class to CourseOutlineFragment.
- Rename NewCourseOutlineActivity class to CourseOutlineActivity.

* Release 2.14

- LEARNER-4781
- Update whats_new json files
- Update whats new images
- Update english and spanish strings

* Testing Transifex update through Travis

* Revert "Test Transifex update through Travis"

* Remove problematic check which was causing the issues.

- LEARNER-4793
- Due to the this check there were possible scenarios in which user
tried to start bulk download but it didn’t get actually started due to
no internet connectivity or other reason and we were still firing the
‘BulkVideosDownloadStartedEvent’ event.

* Update Travis config to only run builds on all Pull Requests

- LEARNER-4338
- Reverts: LEARNER-2367
Due to this change Travis will checkout current master and put all of
the changes done in a PR on top of it through a commit and run tests on
it. This will be valid for all PRs i.e. internal and externals (OSPRs).

* Remove the ignoring of NewApi Lint check

- LEARNER-3115
Reverts the commit (63d9e07) from PR #1019
Issue's link on Travis Github:
travis-ci/travis-ci#8676

* Fix NewApi usage

* Improve parsing of Registration form API

- LEARNER-5403
- Add PLAINTEXT field type
- Remove CHECKBOX field type and all related classes that were being
used to make agreement text/checkbox items on the Register screen.

* Add TLS 1.2 protocol support for Pre-Lollipop Devices

- LEARNER-5406
TLS 1.2 isn't by default enabled on Pre-Lollipop Devices which is the
protocol that our backend has updated to. This commit enables it so that
server-client communication is seamless.

Inspiration for this fix:
square/okhttp#2372 (comment)

* Force Glide to use our version of OkHttp which now supports TLS 1.2

Without this forcing, Glide isn't able to load images on Pre-Lollipop
devices.

* Decode HTML entities in Video Transcripts

- LEARNER-5190
Handles the case when multiple HTML entities translate to one character
e.g. {@literal &amp;#39;} which is essentially an apostrophe that should
 normally occur as {@literal &#39;}.

* Force Glide to use our version of OkHttp only on Pre-lollipop devices

* Bump minSdkVersion from 14 to 16

Due to TLS 1.2 implementation on the backend we need to stop supporting
Android versions lesser than 16, as the support for TLS 1.1 and 1.2 came
in JellyBean i.e. API Level 16.
Ref: https://developer.android.com/reference/javax/net/ssl/SSLSocket

* Update Enroll Now Button Message for Professional Education Courses

- LEARNER-4643

* Server redirection exists in the web page urls will be render within app.

- LEARNER-4643
- In some of the cases server redirects the page url to other hosting
url, we have screens in our app for e.g. Course Detail, Announcements
where we are only allowing initial page urls to render and redirects
all other urls to external browser. In these specific cases our
intial page url is rendering in external browser due to server side
redirection. This issue has been fixed in this commit. If it will be
the redirection from serverside within initial page url loading, it
will render within app.

* Ignore the logging of branch sdk errors occurred due to no internet.

- LEARNER-4839

* Add Subjects Discovery on Discovery Screen

- LEARNER-4284
- Feature is kept behind the feature flag: SUBJECT_DISOVERY_ENABLED
- Browse by subject screen supports both orientations
- Refactored onPagePartiallyLoaded() to
onPageLoadProgressChanged(WebView view, int progress) which will now
allow us to decide based on how much a page has been loaded inside a
WebView.
* All previous usages of onPagePartiallyLoaded() have been updated.
- Standardise URL building and add tests

* Add initial support of landscape mode in some screens.

> LEARNER-3384
> Enable landscape mode in MainDashboardActivity, CourseTabsDashboardActivity,
CourseOutlineActivity, CourseHandoutActivity, CourseAnnouncementActivity and
DownloadListActivity screens.
> Done following fixes after enabling landscape mode on these screens
- Stretch tabs of tabs layout to max of its available width.
- Don’t show ‘Find a course’ card on ‘Courses’ fragment until the screen loads.
- Fixed spiral progress bar stops redrawing itself issue. The issue occurs in
spiral progress bar for video downloading, it works fine when in one orientation
(either portrait or landscape) but when you change the orientation it stops
redrawing itself.
- Update progress wheel library, update is avoiding use of handler.
- Avoid the recreation of DownloadSizeExceed Dialog on orientation change.
As a quick fix, avoid the recreation of dialog on orientation change to
avoid problematic scenarios For e.g. cancel button stops working on
orientation change, we have to fix it properly which is explained and
planned to implement in story LEARNER-2177.
- Removing all downloads from native download manager initially.
It has been done to avoid possible issues for example: #1106 (comment)

* Add Find a Course footer properly

- LEARNER-5785
Find a Course is now added even when user doesn't have enrolled in any
course.

* Add initial support of landscape mode in some screens.

> LEARNER-3384
> Enable landscape mode in MainDashboardActivity, CourseTabsDashboardActivity,
CourseOutlineActivity, CourseHandoutActivity, CourseAnnouncementActivity and
DownloadListActivity screens.
> Done following fixes after enabling landscape mode on these screens
- Stretch tabs of tabs layout to max of its available width.
- Don’t show ‘Find a course’ card on ‘Courses’ fragment until the screen loads.
- Fixed spiral progress bar stops redrawing itself issue. The issue occurs in
spiral progress bar for video downloading, it works fine when in one orientation
(either portrait or landscape) but when you change the orientation it stops
redrawing itself.
- Update progress wheel library, update is avoiding use of handler.
- Avoid the recreation of DownloadSizeExceed Dialog on orientation change.
As a quick fix, avoid the recreation of dialog on orientation change to
avoid problematic scenarios For e.g. cancel button stops working on
orientation change, we have to fix it properly which is explained and
planned to implement in story LEARNER-2177.
- Removing all downloads from native download manager initially.
It has been done to avoid possible issues for example: #1106 (comment)

* Update WhatsNew messages and images

- LEARNER-5385
- strings.xml updated
- WhatsNew images and json updated
- Auto-format whats_new json files

* Centrally align texts on WhatsNew screen

* Add Find a Course footer properly

- LEARNER-5785
Find a Course is now added even when user doesn't have enrolled in any
course.

* Remove unnecessary permission READ_PHONE_STATE

- LEARNER-5919
Currently we are only using the TelephonyManager class's
`getNetworkOperator` function which doesn't require the
android.permission.READ_PHONE_STATE permission.

Usage in code: org/edx/mobile/util/NetworkUtil.java:99

* Update gradle and some other libraries mentioned below

- Updated gradle version to 4.4
- Updated android gradle pluggin version to 3.1.3
- Updated google services gradle Plugin to 4.0.1
- Shifted to AAPT2 (As android plugin 3.0.0 enables AAPT2 by default)
- Updated build tools to 27.0.3
- Updated target sdk version to 27
- Updated compile sdk version to 27
- Updated android support libraries to 27.1.1
- Updated groovy to 2.4.12
- Updated play services to 15.0.1
- Updated firebase-core to 16.0.1

Ref doc: https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration

- LEARNER-5799

* Fixed errors that occurs due to enabling of AAPT2 tool.

- Android plugin 3.0.0 enables AAPT2 by default.
- Ref: https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration

* Fixed lint errors.

* Disable RoboBlender to avoid annotation processor issues.

* Add the constants.gradle file & move common gradle level constants to it

* Fix status bar color issue after updating support library.

* Update travis.yml file after updating build tools and target sdk version

* [FIXME] Disable test cases run on travis for the time being.

After shifting to AAPT2 build system, Robolectric library needs to
be updated as well to support AAPT2 changes, which we shall cover in
LEARNER-5469 story. So, for the success of travis builds and to make this
PR mergeable into master, test cases have been disabled for the time being.
This commit must be reverted in LEARNER-5469 story.

* UserProfileActivity NullPointerException crash resolved

on low memory user profile screen crash when relaunch

* Improve Sign in flow, show proper error message in case of error below.

- LEARNER-5672
- Proper error message will be shown now in sign in case when user try to
login with the new Gmail/FB account which is not linked to any edX account.
Server returns 400 error code in this case.

* Camera and Read Storage Permissions Added

- LEARNER-5917
- Sdk >= 22 andorid needs runtime permissions for using camera and accessing
  photos from gallery
- Camera permission required for capturing image and use as profile picture
- Read Storage Permission required for getting image and use as profile picture
- Above sdk 24 android dont allow to share file to other apps so provider is
  required for sharing file uri, which has been added

* Update Fabric suite

- LEARNER-5682
- Branch version from 1.14.5 to 2.19.2
- Crashlytics version from 2.9.1 to 2.9.5
- Answers integration inside the Branch has also been removed cuz we
already have that inside Crashlytics SDK

* Delete legacy Branch integration code

* Added support for push notifications in the release topic

[LEARNER-5811]

Adds in support for Push Notifications through FCM using
a release topic. This topic will be used to send release updates to
the application.

* Updates for new version of Firebase and build.gradle upgrade

* Write External Storage Permission Added

- LEARNER-5920
- SDK >= 22 Andorid needs runtime permissions for downloading videos.
- Write Storage Permission required for downloading and saving videos
  (single and bulk both).
- Permission querying mechanism has been generalized and moved to
  BaseFragment class.
- Check and Ask permissions implementation for editProfile Screen also
  change according to new implementation using BaseFragment
- Removed the usage of the deprecated attribute
  DownloadManager.COLUMN_LOCAL_FILENAME in favor of
  DownloadManager.COLUMN_LOCAL_URI

* Update Facebook SDK to 4.36.0

- LEARNER-5572

* UX improvement on discussion forum buttons

This commit improves the buttons "report", "vote" and "like" to assume
success and update as soon the user presses them.  This is along current
android best practices.

* Country spinner scroll issue resolved

- Issue resolved by removing 'popupTheme' in style.xml

* Revert "[FIXME] Disable test cases run on travis for the time being."

This reverts commit 86be4b5.

* Done with the changes needed to upgrade Robolectric to version 3.8

- LEARNER-5469

* Fix injection issue on pre-lollipop devices

* Bump minSdkVersion to KitKat (API Level 19)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment