Skip to content
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

Switch to Firebase Crashlytics #175

Merged
merged 1 commit into from May 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion Android/app/build.gradle
@@ -1,4 +1,5 @@
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'

// See https://developer.android.com/studio/publish/app-signing#secure-shared-keystore
def keystorePropertiesFile = rootProject.file("keystore.properties")
Expand Down Expand Up @@ -107,7 +108,7 @@ dependencies {
// For Firebase Analytics, etc.
implementation 'com.google.firebase:firebase-core:16.0.9'
implementation 'com.google.firebase:firebase-perf:16.2.5' // Last version to support API <17
implementation 'com.google.firebase:firebase-crash:16.2.1'
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.0'
// For Sockslib
implementation 'org.slf4j:slf4j-api:1.7.25'
implementation 'org.slf4j:slf4j-android:1.7.25'
Expand Down
2 changes: 1 addition & 1 deletion Android/app/src/main/AndroidManifest.xml
Expand Up @@ -40,7 +40,7 @@
</receiver>

<meta-data
android:name="firebase_crash_collection_enabled"
android:name="firebase_crashlytics_collection_enabled"
android:value="@bool/FIREBASE_ENABLED"/>
<meta-data
android:name="firebase_analytics_collection_enabled"
Expand Down
6 changes: 3 additions & 3 deletions Android/app/src/main/java/app/intra/net/dns/DnsUdpQuery.java
Expand Up @@ -18,7 +18,7 @@
import android.os.SystemClock;
import android.util.Log;
import app.intra.sys.LogWrapper;
import com.google.firebase.crash.FirebaseCrash;
import com.crashlytics.android.Crashlytics;
import java.net.InetAddress;
import java.net.ProtocolException;

Expand Down Expand Up @@ -49,14 +49,14 @@ public static DnsUdpQuery fromUdpBody(byte[] dnsPacketData) {
return null;
}
if (!dnsPacket.isNormalQuery() && !dnsPacket.isResponse()) {
FirebaseCrash.logcat(Log.INFO, LOG_TAG, "Dropping strange DNS query");
Crashlytics.log(Log.INFO, LOG_TAG, "Dropping strange DNS query");
return null;
}

dnsUdpQuery.type = dnsPacket.getQueryType();
dnsUdpQuery.name = dnsPacket.getQueryName();
if (dnsUdpQuery.name == null || dnsUdpQuery.type == 0) {
FirebaseCrash.logcat(Log.INFO, LOG_TAG, "No question in DNS packet");
Crashlytics.log(Log.INFO, LOG_TAG, "No question in DNS packet");
return null;
}
dnsUdpQuery.requestId = dnsPacket.getId();
Expand Down
10 changes: 5 additions & 5 deletions Android/app/src/main/java/app/intra/net/doh/Resolver.java
Expand Up @@ -18,7 +18,7 @@
import android.util.Log;
import app.intra.net.dns.DnsUdpQuery;
import app.intra.sys.LogWrapper;
import com.google.firebase.crash.FirebaseCrash;
import com.crashlytics.android.Crashlytics;
import java.io.IOException;
import java.net.SocketTimeoutException;
import java.nio.BufferOverflowException;
Expand Down Expand Up @@ -95,11 +95,11 @@ public void onFailure(Call call, IOException e) {
Transaction.Status.CANCELED : Transaction.Status.SEND_FAIL;
LogWrapper.logcat(Log.WARN, LOG_TAG, "Failed to read HTTPS response: " + e.toString());
if (e instanceof SocketTimeoutException) {
FirebaseCrash.logcat(Log.WARN, LOG_TAG, "Workaround for OkHttp3 #3146: resetting");
Crashlytics.log(Log.WARN, LOG_TAG, "Workaround for OkHttp3 #3146: resetting");
try {
serverConnection.reset();
} catch (NullPointerException npe) {
FirebaseCrash.logcat(Log.WARN, LOG_TAG,
Crashlytics.log(Log.WARN, LOG_TAG,
"Unlikely race: Null server connection at reset.");
}
}
Expand All @@ -123,15 +123,15 @@ private void processResponse(Response response) {
try {
writeRequestIdToDnsResponse(dnsResponse, dnsUdpQuery.requestId);
} catch (BufferOverflowException e) {
FirebaseCrash.logcat(Log.WARN, LOG_TAG, "ID replacement failed");
Crashlytics.log(Log.WARN, LOG_TAG, "ID replacement failed");
transaction.status = Transaction.Status.BAD_RESPONSE;
return;
}
DnsUdpQuery parsedDnsResponse = DnsUdpQuery.fromUdpBody(dnsResponse);
if (parsedDnsResponse != null) {
Log.d(LOG_TAG, "RNAME: " + parsedDnsResponse.name + " NAME: " + dnsUdpQuery.name);
if (!dnsUdpQuery.name.equals(parsedDnsResponse.name)) {
FirebaseCrash.logcat(Log.ERROR, LOG_TAG, "Mismatch in request and response names.");
Crashlytics.log(Log.ERROR, LOG_TAG, "Mismatch in request and response names.");
transaction.status = Transaction.Status.BAD_RESPONSE;
return;
}
Expand Down
Expand Up @@ -23,7 +23,7 @@
import app.intra.net.VpnAdapter;
import app.intra.sys.IntraVpnService;
import app.intra.sys.LogWrapper;
import com.google.firebase.crash.FirebaseCrash;
import com.crashlytics.android.Crashlytics;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
Expand Down Expand Up @@ -169,7 +169,7 @@ private static ParcelFileDescriptor establishVpn(IntraVpnService vpnService) {
.addDisallowedApplication(vpnService.getPackageName())
.establish();
} catch (Exception e) {
FirebaseCrash.report(e);
Crashlytics.logException(e);
return null;
}
}
Expand Down
43 changes: 21 additions & 22 deletions Android/app/src/main/java/app/intra/net/split/SplitVpnAdapter.java
Expand Up @@ -26,7 +26,7 @@
import app.intra.net.doh.ResponseWriter;
import app.intra.net.doh.Transaction;
import app.intra.sys.IntraVpnService;
import com.google.firebase.crash.FirebaseCrash;
import com.crashlytics.android.Crashlytics;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
Expand Down Expand Up @@ -96,7 +96,7 @@ private static ParcelFileDescriptor establishVpn(IntraVpnService vpnService) {
PrivateAddress privateIpv6Address = new PrivateAddress(IPV6_SUBNET, 120);
PrivateAddress privateIpv4Address = selectPrivateAddress();
if (privateIpv4Address == null) {
FirebaseCrash.logcat(
Crashlytics.log(
Log.ERROR, LOG_TAG, "Unable to find a private address on which to establish a VPN.");
return null;
}
Expand All @@ -122,13 +122,13 @@ private static ParcelFileDescriptor establishVpn(IntraVpnService vpnService) {
}
tunFd = builder.establish();
} catch (IllegalArgumentException e) {
FirebaseCrash.report(e);
Crashlytics.logException(e);
Log.e(LOG_TAG, establishVpnErrorMsg, e);
} catch (SecurityException e) {
FirebaseCrash.report(e);
Crashlytics.logException(e);
Log.e(LOG_TAG, establishVpnErrorMsg, e);
} catch (IllegalStateException e) {
FirebaseCrash.report(e);
Crashlytics.logException(e);
Log.e(LOG_TAG, establishVpnErrorMsg, e);
}

Expand Down Expand Up @@ -167,7 +167,7 @@ private static PrivateAddress selectPrivateAddress() {
try {
netInterfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
} catch (SocketException e) {
FirebaseCrash.report(e);
Crashlytics.logException(e);
e.printStackTrace();
return null;
}
Expand Down Expand Up @@ -199,12 +199,12 @@ private static PrivateAddress selectPrivateAddress() {
@Override
// This thread reads DNS requests from the VPN interface and forwards them via |serverConnection|.
public void run() {
FirebaseCrash.logcat(Log.DEBUG, LOG_TAG, "Query thread starting");
Crashlytics.log(Log.DEBUG, LOG_TAG, "Query thread starting");
if (tunFd == null) {
// This check is necessary due to a race, where the VPN has been closed and the device regains
// network connectivity before the service stops. As a result the TUN file descriptor is null
// at the time the resolver is created.
FirebaseCrash.logcat(Log.WARN, LOG_TAG, "VPN/TUN file descriptor is null");
Crashlytics.log(Log.WARN, LOG_TAG, "VPN/TUN file descriptor is null");
return;
}

Expand All @@ -218,8 +218,8 @@ public void run() {
length = in.read(buffer.array());
} catch (IOException e) {
if (!isInterrupted()) {
FirebaseCrash.logcat(Log.ERROR, LOG_TAG, "Failed to read from tun interface.");
FirebaseCrash.report(e);
Crashlytics.log(Log.ERROR, LOG_TAG, "Failed to read from tun interface.");
Crashlytics.logException(e);
}
return;
}
Expand All @@ -233,7 +233,7 @@ public void run() {
continue;
}
if (length < IP_MIN_HEADER_LENGTH) {
FirebaseCrash.logcat(Log.WARN, LOG_TAG, "Received malformed IP packet.");
Crashlytics.log(Log.WARN, LOG_TAG, "Received malformed IP packet.");
continue;
}
buffer.limit(length);
Expand All @@ -248,30 +248,29 @@ public void run() {
ipPacket = new Ipv6Packet(buffer);
}
} catch (IllegalArgumentException e) {
FirebaseCrash
.logcat(Log.WARN, LOG_TAG, "Received malformed IP packet: " + e.getMessage());
Crashlytics.log(Log.WARN, LOG_TAG, "Received malformed IP packet: " + e.getMessage());
continue;
}
byte protocol = ipPacket.getProtocol();
if (protocol != UDP_PROTOCOL) {
FirebaseCrash.logcat(Log.WARN, LOG_TAG, getProtocolErrorMessage(protocol));
Crashlytics.log(Log.WARN, LOG_TAG, getProtocolErrorMessage(protocol));
continue;
}

UdpPacket udpPacket = new UdpPacket(ByteBuffer.wrap(ipPacket.getPayload()));
if (udpPacket.destPort != DNS_DEFAULT_PORT) {
FirebaseCrash.logcat(Log.WARN, LOG_TAG, "Received non-DNS UDP packet");
Crashlytics.log(Log.WARN, LOG_TAG, "Received non-DNS UDP packet");
continue;
}

if (udpPacket.length == 0) {
FirebaseCrash.logcat(Log.INFO, LOG_TAG, "Received interrupt UDP packet.");
Crashlytics.log(Log.INFO, LOG_TAG, "Received interrupt UDP packet.");
continue;
}

DnsUdpQuery dnsRequest = DnsUdpQuery.fromUdpBody(udpPacket.data);
if (dnsRequest == null) {
FirebaseCrash.logcat(Log.ERROR, LOG_TAG, "Failed to parse DNS request");
Crashlytics.log(Log.ERROR, LOG_TAG, "Failed to parse DNS request");
continue;
}
Log.d(
Expand All @@ -292,8 +291,8 @@ public void run() {
dnsRequest, udpPacket.data, this);
} catch (Exception e) {
if (!isInterrupted()) {
FirebaseCrash.logcat(Log.WARN, LOG_TAG, "Unexpected exception in UDP loop.");
FirebaseCrash.report(e);
Crashlytics.log(Log.WARN, LOG_TAG, "Unexpected exception in UDP loop.");
Crashlytics.logException(e);
}
}
}
Expand Down Expand Up @@ -345,8 +344,8 @@ public void sendResult(DnsUdpQuery dnsUdpQuery, Transaction transaction) {
try {
out.write(rawIpResponse);
} catch (IOException e) {
FirebaseCrash.logcat(Log.ERROR, LOG_TAG, "Failed to write to VPN/TUN interface.");
FirebaseCrash.report(e);
Crashlytics.log(Log.ERROR, LOG_TAG, "Failed to write to VPN/TUN interface.");
Crashlytics.logException(e);
transaction.status = Transaction.Status.INTERNAL_ERROR;
}
}
Expand All @@ -359,7 +358,7 @@ public void close() {
try {
tunFd.close();
} catch (IOException e) {
FirebaseCrash.report(e);
Crashlytics.logException(e);
}
}
}
8 changes: 4 additions & 4 deletions Android/app/src/main/java/app/intra/sys/AutoStarter.java
Expand Up @@ -21,7 +21,7 @@
import android.net.VpnService;
import android.util.Log;
import app.intra.ui.MainActivity;
import com.google.firebase.crash.FirebaseCrash;
import com.crashlytics.android.Crashlytics;

/**
* Broadcast receiver that runs on boot, and also when the app is restarted due to an update.
Expand All @@ -31,14 +31,14 @@ public class AutoStarter extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
FirebaseCrash.logcat(Log.DEBUG, LOG_TAG, "Boot event");
Crashlytics.log(Log.DEBUG, LOG_TAG, "Boot event");
VpnController controller = VpnController.getInstance();
VpnState state = controller.getState(context);
if (state.activationRequested && !state.on) {
FirebaseCrash.logcat(Log.DEBUG, LOG_TAG, "Autostart enabled");
Crashlytics.log(Log.DEBUG, LOG_TAG, "Autostart enabled");
if (VpnService.prepare(context) != null) {
// prepare() returns a non-null intent if VPN permission has not been granted.
FirebaseCrash.logcat(Log.WARN, LOG_TAG, "VPN permission not granted. Starting UI.");
Crashlytics.log(Log.WARN, LOG_TAG, "VPN permission not granted. Starting UI.");
Intent startIntent = new Intent(context, MainActivity.class);
startIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startIntent);
Expand Down
24 changes: 12 additions & 12 deletions Android/app/src/main/java/app/intra/sys/IntraVpnService.java
Expand Up @@ -46,8 +46,8 @@
import app.intra.net.split.SplitVpnAdapter;
import app.intra.sys.NetworkManager.NetworkListener;
import app.intra.ui.MainActivity;
import com.crashlytics.android.Crashlytics;
import com.google.firebase.analytics.FirebaseAnalytics;
import com.google.firebase.crash.FirebaseCrash;
import java.util.Calendar;

public class IntraVpnService extends VpnService implements NetworkListener,
Expand Down Expand Up @@ -292,7 +292,7 @@ private synchronized void startVpn() {

VpnController.getInstance().onStartComplete(this, vpnAdapter != null);
if (vpnAdapter == null) {
FirebaseCrash.logcat(Log.WARN, LOG_TAG, "Failed to startVpn VPN adapter");
Crashlytics.log(Log.WARN, LOG_TAG, "Failed to startVpn VPN adapter");
stopSelf();
}
}
Expand All @@ -310,13 +310,13 @@ private synchronized void restartVpn() {
if (vpnAdapter != null) {
vpnAdapter.start();
} else {
FirebaseCrash.logcat(Log.WARN, LOG_TAG, "Restart failed");
Crashlytics.log(Log.WARN, LOG_TAG, "Restart failed");
}
}

@Override
public void onCreate() {
FirebaseCrash.logcat(Log.INFO, LOG_TAG, "Creating DNS VPN service");
Crashlytics.log(Log.INFO, LOG_TAG, "Creating DNS VPN service");
VpnController.getInstance().setIntraVpnService(this);

firebaseAnalytics = FirebaseAnalytics.getInstance(this);
Expand All @@ -326,7 +326,7 @@ public void onCreate() {

public void signalStopService(boolean userInitiated) {
// TODO(alalama): display alert if not user initiated
FirebaseCrash.logcat(
Crashlytics.log(
Log.INFO,
LOG_TAG,
String.format("Received stop signal. User initiated: %b", userInitiated));
Expand All @@ -353,12 +353,12 @@ private VpnAdapter makeVpnAdapter() {

private synchronized void startVpnAdapter() {
if (vpnAdapter == null) {
FirebaseCrash.logcat(Log.INFO, LOG_TAG, "Starting DNS resolver");
Crashlytics.log(Log.INFO, LOG_TAG, "Starting DNS resolver");
vpnAdapter = makeVpnAdapter();
if (vpnAdapter != null) {
vpnAdapter.start();
} else {
FirebaseCrash.logcat(Log.ERROR, LOG_TAG, "Failed to start VPN adapter!");
Crashlytics.log(Log.ERROR, LOG_TAG, "Failed to start VPN adapter!");
}
}
}
Expand All @@ -373,7 +373,7 @@ private synchronized void stopVpnAdapter() {

@Override
public synchronized void onDestroy() {
FirebaseCrash.logcat(Log.INFO, LOG_TAG, "Destroying DNS VPN service");
Crashlytics.log(Log.INFO, LOG_TAG, "Destroying DNS VPN service");

PreferenceManager.getDefaultSharedPreferences(this).
unregisterOnSharedPreferenceChangeListener(this);
Expand All @@ -395,7 +395,7 @@ public synchronized void onDestroy() {

@Override
public void onRevoke() {
FirebaseCrash.logcat(Log.WARN, LOG_TAG, "VPN service revoked.");
Crashlytics.log(Log.WARN, LOG_TAG, "VPN service revoked.");
stopVpnAdapter();
stopSelf();

Expand Down Expand Up @@ -450,7 +450,7 @@ public VpnService.Builder newBuilder() {
// Play Store incompatibility is a known issue, so always exclude it.
builder = builder.addDisallowedApplication("com.android.vending");
} catch (PackageManager.NameNotFoundException e) {
FirebaseCrash.report(e);
Crashlytics.logException(e);
Log.e(LOG_TAG, "Failed to exclude an app", e);
}
}
Expand Down Expand Up @@ -505,7 +505,7 @@ private void setNetworkConnected(boolean connected) {
// NetworkListener interface implementation
@Override
public void onNetworkConnected(NetworkInfo networkInfo) {
FirebaseCrash.logcat(Log.INFO, LOG_TAG, "Connected event.");
Crashlytics.log(Log.INFO, LOG_TAG, "Connected event.");
setNetworkConnected(true);
// This code is used to start the VPN for the first time, but startVpn is idempotent, so we can
// call it every time. startVpn performs network activity so it has to run on a separate thread.
Expand All @@ -521,7 +521,7 @@ public void run() {

@Override
public void onNetworkDisconnected() {
FirebaseCrash.logcat(Log.INFO, LOG_TAG, "Disconnected event.");
Crashlytics.log(Log.INFO, LOG_TAG, "Disconnected event.");
setNetworkConnected(false);
VpnController.getInstance().onConnectionStateChanged(this, null);
}
Expand Down