Skip to content

Commit

Permalink
Need to add android:usesCleartextTraffic="true" attribute to applicat…
Browse files Browse the repository at this point in the history
…ion in manifest since API 28 restricts cleartext rxtx by default
  • Loading branch information
Steven Contreras committed Jun 28, 2018
1 parent 7170b4c commit 84c3044
Show file tree
Hide file tree
Showing 6 changed files with 183 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@
<manifest package="go_spatial.com.github.tegola.mobile.android.controller"
xmlns:android="http://schemas.android.com/apk/res/android">

<uses-sdk android:minSdkVersion="15" android:maxSdkVersion="26"/>
<uses-sdk android:minSdkVersion="16" android:maxSdkVersion="28"/>

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_LOGS"/>
<!--<uses-permission android:name="android.permission.READ_LOGS"/>-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application>
<application
android:allowBackup="true"
android:supportsRtl="true"
android:usesCleartextTraffic="true">

<service android:name="go_spatial.com.github.tegola.mobile.android.controller.FGS"/>
<activity android:name="go_spatial.com.github.tegola.mobile.android.controller.ASNBContentActivity"/>
</application>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,17 @@
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Properties;
Expand All @@ -28,7 +38,18 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import javax.security.cert.CertificateException;

import okhttp3.Call;
import okhttp3.ConnectionSpec;
import okhttp3.Dispatcher;
import okhttp3.Headers;
import okhttp3.HttpUrl;
Expand Down Expand Up @@ -267,6 +288,117 @@ public static boolean isValidUrl(String url) {
return false;
}

private static Dispatcher newDefaultDispatcher() {
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequestsPerHost(20);
return dispatcher;
}

private static X509TrustManager newDefaultX509TrustManager() {
TrustManagerFactory trustManagerFactory = null;
X509TrustManager trustManager = null;
try {
trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore)null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
Log.d(TAG, String.format("newDefaultX509TrustManager: trustManagerFactory.getTrustManagers(): %s", Arrays.toString(trustManagers)));
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager))
throw new IllegalStateException(String.format("Unexpected default trust managers: %s", Arrays.toString(trustManagers)));
trustManager = (X509TrustManager)trustManagers[0];
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return trustManager;
}

private static X509TrustManager newX509TrustManagerBypass() {
return new X509TrustManager() {
private final String TAG = "X509TrustManagerBypass";

@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
Log.d(TAG, "checkClientTrusted: no-op for bypass");
}

@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {
Log.d(TAG, "checkServerTrusted: no-op for bypass");
}

@Override
public X509Certificate[] getAcceptedIssuers() {
Log.d(TAG, "getAcceptedIssuers: returning java.security.cert.X509Certificate[]{} for bypass");
return new java.security.cert.X509Certificate[]{};
}
};
}

private static class SSLConfig {
SSLContext sslContext = null;
KeyManager[] keyManagers = null;
TrustManager[] trustManagers = null;
SecureRandom random = null;
}
private static SSLConfig newSSLConfig(final String sslprotocol, KeyManager[] keyManagers, final TrustManager[] trustManagers, final SecureRandom random) {
SSLConfig sslConfig = new SSLConfig();
sslConfig.keyManagers = keyManagers;
sslConfig.trustManagers = trustManagers;
sslConfig.random = random;
try {
sslConfig.sslContext = SSLContext.getInstance(sslprotocol); //see https://developer.android.com/reference/javax/net/ssl/SSLContext.html#getInstance(java.lang.String) for list of canonical protocol strings
Log.d(TAG, String.format("newSSLConfig: sslContext.getProtocol(): %s", sslConfig.sslContext.getProtocol()));
sslConfig.sslContext.init(keyManagers, trustManagers, random);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return sslConfig;
}
private static SSLConfig newSSLConfig(final String sslprotocol) {
return newSSLConfig(sslprotocol, null, new TrustManager[]{newDefaultX509TrustManager()}, null);
}

private static HostnameVerifier newDefaultHostnameVerifier() {
return new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
};
}

private static OkHttpClient.Builder newDefaultHttpClientBuilder(final boolean useSSL) {
final OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder()
.dispatcher(newDefaultDispatcher())
.protocols(new ArrayList<Protocol>(){{add(Protocol.HTTP_1_1);}}) //restrict to HTTP 1.1
.readTimeout(20, TimeUnit.SECONDS);
if (useSSL) {
try {
SSLConfig sslConfig = newSSLConfig("SSL");
httpClientBuilder.sslSocketFactory(sslConfig.sslContext.getSocketFactory(), (X509TrustManager)sslConfig.trustManagers[0]);
httpClientBuilder.hostnameVerifier(newDefaultHostnameVerifier());
httpClientBuilder.connectionSpecs(new ArrayList<ConnectionSpec>(){{add(new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS).build());}});
} catch (Exception e) {
e.printStackTrace();
}
}
return httpClientBuilder;
}
private static OkHttpClient.Builder newDefaultHttpClientBuilder() {
return newDefaultHttpClientBuilder(false);
}

private static OkHttpClient newDefaultHttpClient() {
return newDefaultHttpClientBuilder().build();
}

public static class Get {
private final static String TAG = Utils.HTTP.Get.class.getCanonicalName();

Expand All @@ -277,19 +409,10 @@ public interface ContentHandler {
void onReadComplete(long n_read, long n_remaining);
}

private static Dispatcher getDispatcher() {
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequestsPerHost(20);
return dispatcher;
}

public static void exec(final String s_url, final ContentHandler content_handler) {
if (s_url == null)
throw new NullPointerException("s_url cannot be null");
final OkHttpClient httpClient = new OkHttpClient.Builder().dispatcher(getDispatcher())
.protocols(new ArrayList<Protocol>(){{add(Protocol.HTTP_1_1);}}) //restrict to HTTP 1.1
.readTimeout(20, TimeUnit.SECONDS)
.build();
final OkHttpClient httpClient = newDefaultHttpClient();
final Request http_get_request = new Request.Builder()
.url(s_url)
.get()
Expand Down Expand Up @@ -747,12 +870,6 @@ private void request_file_download(@NonNull final OkHttpClient httpClient, @NonN
}
}

private static Dispatcher getDispatcher() {
Dispatcher dispatcher = new Dispatcher();
dispatcher.setMaxRequestsPerHost(20);
return dispatcher;
}

@Override
protected Exception doInBackground(final HttpUrl_To_Local_File[] httpUrl_to_local_file) {
Exception exception = null;
Expand All @@ -765,10 +882,8 @@ protected Exception doInBackground(final HttpUrl_To_Local_File[] httpUrl_to_loca
throw new RemoteFileInvalidParameterException("HttpUrl_To_Local_File.url is null");
if (httpUrl_to_local_file[0].get_file() == null)
throw new RemoteFileInvalidParameterException("HttpUrl_To_Local_File.file is null");
httpClient = new OkHttpClient.Builder().dispatcher(getDispatcher())
.protocols(new ArrayList<Protocol>(){{add(Protocol.HTTP_1_1);}}) //restrict to HTTP 1.1
httpClient = newDefaultHttpClientBuilder()
.followRedirects(true)
.readTimeout(20, TimeUnit.SECONDS)
//network interceptor not currently needed - only application interceptor
// .addNetworkInterceptor(new Interceptor() {
// @Override public Response intercept(Chain chain) throws IOException {
Expand Down
3 changes: 2 additions & 1 deletion android/TMHarness/TMHarnessUX/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="go_spatial.com.github.tegola.mobile.android.ux">

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_LOGS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Expand All @@ -17,6 +17,7 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="@style/AppTheme">

<!--
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.PersistableBundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AlertDialog;
Expand Down Expand Up @@ -101,8 +102,6 @@ protected void onCreate(Bundle savedInstanceState) {

m_btn_install_remote_gpkg_bundle__cancel.setOnClickListener(OnClickListener__m_btn_install_remote_gpkg_bundle__cancel);
m_btn_install_remote_gpkg_bundle.setOnClickListener(OnClickListener__m_btn_install_remote_gpkg_bundle);

getGpkgBundlesAvailable();
}

private LinkedHashMap<String, ArrayList<String>> m_gpkg_bundles_available = null;
Expand Down Expand Up @@ -191,6 +190,10 @@ protected void onPostCreate(@Nullable Bundle savedInstanceState) {

m_pb.setMax(PROG_MAX);
m_vw_progress.setVisibility(View.GONE);

m_edt_remote_gpkg_bundle__name.requestFocus();

getGpkgBundlesAvailable();
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,8 @@
android:inputType="textUri"
android:singleLine="true"
android:text=""
android:textSize="14sp" />
android:textSize="14sp"
android:nextFocusDown="@+id/edt_remote_gpkg_bundle__ver_props"/>

</RelativeLayout>

Expand Down Expand Up @@ -213,7 +214,8 @@
android:inputType="textUri"
android:singleLine="true"
android:text=""
android:textSize="14sp" />
android:textSize="14sp"
android:nextFocusDown="@+id/btn_install_remote_gpkg_bundle"/>

</RelativeLayout>

Expand All @@ -238,49 +240,45 @@
style="@style/Section_Content_Item_Content"
android:orientation="horizontal">

<EditText
android:id="@+id/edt_local_gpkg_bundle__name"
style="@style/edittext"
android:gravity="center_vertical"
android:layout_centerVertical="true"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:imeOptions="actionDone"
android:inputType="textUri"
android:singleLine="true"
android:text=""
android:textSize="14sp"/>
android:layout_alignParentStart="true">

<EditText
android:id="@+id/edt_local_gpkg_bundle__name"
style="@style/edittext"
android:gravity="center_vertical"
android:layout_centerVertical="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionDone"
android:inputType="textUri"
android:singleLine="true"
android:text=""
android:textSize="14sp"/>

<Button
android:id="@+id/btn_install_remote_gpkg_bundle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_marginTop="30dp"
android:drawableLeft="@drawable/ic_download_black_24dp"
android:drawablePadding="5dp"
android:text="@string/install" />

</LinearLayout>

</RelativeLayout>

</LinearLayout>
<!-- install gpkg bundle - selection - name: END -->

<!-- install gpkg bundle - DO IT button - name: BEGIN -->


<RelativeLayout
style="@style/Section_Content_Item_Content"
android:orientation="horizontal"
android:layout_marginTop="20dp">
<Button
android:id="@+id/btn_install_remote_gpkg_bundle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:drawableLeft="@drawable/ic_download_black_24dp"
android:drawablePadding="5dp"
android:text="@string/install"
/>

</RelativeLayout>
<!-- install gpkg bundle - DO IT button - END -->

<!-- install gpkg bundle - progress - name: BEGIN -->
<LinearLayout
android:id="@+id/sect_content__item__install_remote_gpkg_bundle__progress"
Expand Down
6 changes: 3 additions & 3 deletions android/TMHarness/TMHarnessUX/version.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Wed Jun 27 14:32:20 PDT 2018
#Thu Jun 28 15:20:24 PDT 2018
VERSION_MINOR=3
VERSION_BUILD=209
VERSION_CODE=17
VERSION_BUILD=239
VERSION_CODE=18
VERSION_SUBMINOR=3
VERSION_MAJOR=1

0 comments on commit 84c3044

Please sign in to comment.