Skip to content

Fix offline transport handling. #537

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

Merged
merged 1 commit into from
Jun 19, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import com.google.android.datatransport.cct.proto.LogResponse;
import com.google.android.datatransport.cct.proto.NetworkConnectionInfo;
import com.google.android.datatransport.cct.proto.NetworkConnectionInfo.MobileSubtype;
import com.google.android.datatransport.cct.proto.NetworkConnectionInfo.NetworkType;
import com.google.android.datatransport.cct.proto.QosTierConfiguration;
import com.google.android.datatransport.runtime.EventInternal;
import com.google.android.datatransport.runtime.backends.BackendRequest;
Expand Down Expand Up @@ -65,6 +66,9 @@ final class CctTransportBackend implements TransportBackend {
private static final String CONTENT_TYPE_HEADER_KEY = "Content-Type";
private static final String PROTOBUF_CONTENT_TYPE = "application/x-protobuf";

@VisibleForTesting static final String KEY_NETWORK_TYPE = "net-type";
@VisibleForTesting static final String KEY_MOBILE_SUBTYPE = "mobile-subtype";

private static final String KEY_SDK_VERSION = "sdk-version";
private static final String KEY_MODEL = "model";
private static final String KEY_HARDWARE = "hardware";
Expand All @@ -73,8 +77,6 @@ final class CctTransportBackend implements TransportBackend {
private static final String KEY_OS_BUILD = "os-uild";
private static final String KEY_MANUFACTURER = "manufacturer";
private static final String KEY_FINGERPRINT = "fingerprint";
private static final String KEY_NETWORK_TYPE = "net-type";
private static final String KEY_MOBILE_SUBTYPE = "mobile-subtype";
private static final String KEY_TIMEZONE_OFFSET = "tz-offset";

private final ConnectivityManager connectivityManager;
Expand Down Expand Up @@ -125,12 +127,25 @@ public EventInternal decorate(EventInternal eventInternal) {
.addMetadata(KEY_MANUFACTURER, Build.MANUFACTURER)
.addMetadata(KEY_FINGERPRINT, Build.FINGERPRINT)
.addMetadata(KEY_TIMEZONE_OFFSET, getTzOffset())
.addMetadata(KEY_NETWORK_TYPE, networkInfo.getType())
.addMetadata(KEY_MOBILE_SUBTYPE, toSubtypeValue(networkInfo.getSubtype()))
.addMetadata(KEY_NETWORK_TYPE, getNetTypeValue(networkInfo))
.addMetadata(KEY_MOBILE_SUBTYPE, getNetSubtypeValue(networkInfo))
.build();
}

private int toSubtypeValue(int subtype) {
private static int getNetTypeValue(NetworkInfo networkInfo) {
// when the device is not connected networkInfo returned by ConnectivityManger is null.
if (networkInfo == null) {
return NetworkType.NONE_VALUE;
}
return networkInfo.getType();
}

private static int getNetSubtypeValue(NetworkInfo networkInfo) {
// when the device is not connected networkInfo returned by ConnectivityManger is null.
if (networkInfo == null) {
return MobileSubtype.UNKNOWN_MOBILE_SUBTYPE_VALUE;
}
int subtype = networkInfo.getSubtype();
if (subtype == -1) {
return MobileSubtype.COMBINED_VALUE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import static com.google.android.datatransport.cct.CctTransportBackend.getTzOffset;
import static com.google.android.datatransport.cct.ProtoMatchers.protoMatcher;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;

import android.content.Context;
Expand All @@ -47,6 +48,9 @@
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;

@RunWith(RobolectricTestRunner.class)
public class CctTransportBackendTest {
Expand Down Expand Up @@ -205,4 +209,59 @@ public void send_whenBackendResponseTimesOut_shouldReturnTransientError() {

assertEquals(response, BackendResponse.transientError());
}

@Test
public void decorate_whenOnline_shouldProperlyPopulateNetworkInfo() {
CctTransportBackend backend =
new CctTransportBackend(
RuntimeEnvironment.application, TEST_ENDPOINT, wallClock, uptimeClock, 300);

EventInternal result =
backend.decorate(
EventInternal.builder()
.setEventMillis(INITIAL_WALL_TIME)
.setUptimeMillis(INITIAL_UPTIME)
.setTransportName("3")
.setPayload(PAYLOAD.toByteArray())
.build());

assertThat(result.get(CctTransportBackend.KEY_NETWORK_TYPE))
.isEqualTo(String.valueOf(NetworkConnectionInfo.NetworkType.MOBILE_VALUE));
assertThat(result.get(CctTransportBackend.KEY_MOBILE_SUBTYPE))
.isEqualTo(String.valueOf(NetworkConnectionInfo.MobileSubtype.EDGE_VALUE));
}

@Test
@Config(shadows = {OfflineConnectivityManagerShadow.class})
public void decorate_whenOffline_shouldProperlyPopulateNetworkInfo() {
CctTransportBackend backend =
new CctTransportBackend(
RuntimeEnvironment.application, TEST_ENDPOINT, wallClock, uptimeClock, 300);

EventInternal result =
backend.decorate(
EventInternal.builder()
.setEventMillis(INITIAL_WALL_TIME)
.setUptimeMillis(INITIAL_UPTIME)
.setTransportName("3")
.setPayload(PAYLOAD.toByteArray())
.build());

assertThat(result.get(CctTransportBackend.KEY_NETWORK_TYPE))
.isEqualTo(String.valueOf(NetworkConnectionInfo.NetworkType.NONE_VALUE));
assertThat(result.get(CctTransportBackend.KEY_MOBILE_SUBTYPE))
.isEqualTo(
String.valueOf(NetworkConnectionInfo.MobileSubtype.UNKNOWN_MOBILE_SUBTYPE_VALUE));
}

// When there is no active network, the ConnectivityManager returns null when
// getActiveNetworkInfo() is called.
@Implements(ConnectivityManager.class)
public static class OfflineConnectivityManagerShadow {

@Implementation
public NetworkInfo getActiveNetworkInfo() {
return null;
}
}
}