[Crash Reporting] Only upload Chrome crash reports over unmetered networks.
BUG=702454
TEST=none
R=gsennton@chromium.org, mariakhomenko@chromium.org
Review-Url: https://codereview.chromium.org/2751333004
Cr-Commit-Position: refs/heads/master@{#460227}
diff --git a/android_webview/java/src/org/chromium/android_webview/crash/AwMinidumpUploaderDelegate.java b/android_webview/java/src/org/chromium/android_webview/crash/AwMinidumpUploaderDelegate.java
index 1fe38fb..9be1b77 100644
--- a/android_webview/java/src/org/chromium/android_webview/crash/AwMinidumpUploaderDelegate.java
+++ b/android_webview/java/src/org/chromium/android_webview/crash/AwMinidumpUploaderDelegate.java
@@ -6,7 +6,6 @@
import android.content.Context;
import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
import android.webkit.ValueCallback;
import org.chromium.android_webview.PlatformServiceBridge;
@@ -16,6 +15,7 @@
import org.chromium.base.VisibleForTesting;
import org.chromium.components.minidump_uploader.MinidumpUploaderDelegate;
import org.chromium.components.minidump_uploader.util.CrashReportingPermissionManager;
+import org.chromium.components.minidump_uploader.util.NetworkPermissionUtil;
import java.io.File;
@@ -54,14 +54,10 @@
}
@Override
public boolean isNetworkAvailableForCrashUploads() {
- // JobScheduler will call onStopJob causing our upload to be interrupted when our
- // network requirements no longer hold.
- // TODO(isherman): This code should really be shared with Chrome. Chrome currently
- // checks only whether the network is WiFi (or ethernet) vs. cellular. Most likely,
- // Chrome should instead check whether the network is metered, as is done here.
- NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
- if (networkInfo == null || !networkInfo.isConnected()) return false;
- return !mConnectivityManager.isActiveNetworkMetered();
+ // Note that this is the same critierion that the JobScheduler uses to schedule the
+ // job. JobScheduler will call onStopJob causing our upload to be interrupted when
+ // our network requirements no longer hold.
+ return NetworkPermissionUtil.isNetworkUnmetered(mConnectivityManager);
}
@Override
public boolean isUsageAndCrashReportingPermittedByUser() {
diff --git a/android_webview/java/src/org/chromium/android_webview/crash/CrashReceiverService.java b/android_webview/java/src/org/chromium/android_webview/crash/CrashReceiverService.java
index 22baa75..a84bda3 100644
--- a/android_webview/java/src/org/chromium/android_webview/crash/CrashReceiverService.java
+++ b/android_webview/java/src/org/chromium/android_webview/crash/CrashReceiverService.java
@@ -99,11 +99,8 @@
}
private void scheduleNewJob() {
- JobInfo.Builder builder =
- new JobInfo
- .Builder(TaskIds.WEBVIEW_MINIDUMP_UPLOADING_JOB_ID,
- new ComponentName(this, AwMinidumpUploadJobService.class))
- .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED);
+ JobInfo.Builder builder = new JobInfo.Builder(TaskIds.WEBVIEW_MINIDUMP_UPLOADING_JOB_ID,
+ new ComponentName(this, AwMinidumpUploadJobService.class));
MinidumpUploadJobService.scheduleUpload(this, builder);
}
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 0b67e34..fdf17dab 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -345,6 +345,7 @@
"//chrome/test/android:chrome_java_test_support",
"//components/bookmarks/common/android:bookmarks_java",
"//components/invalidation/impl:java",
+ "//components/minidump_uploader:minidump_uploader_java",
"//components/payments/content:mojom_java",
"//components/payments/content:mojom_parser_java",
"//components/payments/content/android:java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/ChromeMinidumpUploaderDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/ChromeMinidumpUploaderDelegate.java
index 21b6e1d..8e0ec0a 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/crash/ChromeMinidumpUploaderDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/ChromeMinidumpUploaderDelegate.java
@@ -6,13 +6,13 @@
import android.annotation.TargetApi;
import android.content.Context;
import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
import android.os.Build;
import android.os.PersistableBundle;
import org.chromium.chrome.browser.preferences.privacy.PrivacyPreferencesManager;
import org.chromium.components.minidump_uploader.MinidumpUploaderDelegate;
import org.chromium.components.minidump_uploader.util.CrashReportingPermissionManager;
+import org.chromium.components.minidump_uploader.util.NetworkPermissionUtil;
import java.io.File;
@@ -68,15 +68,7 @@
@Override
public boolean isNetworkAvailableForCrashUploads() {
- // TODO(isherman): This code should really be shared with the Android Webview
- // implementation, which tests whether the connection is metered, rather than
- // testing the type of the connection. Implement this change in M59 -- for M58, it's
- // more important to maintain consistency with the previous implementation. When
- // changing this, note that forced uploads do *not* require unmetered connections.
- NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
- if (networkInfo == null || !networkInfo.isConnected()) return false;
- return networkInfo.getType() == ConnectivityManager.TYPE_WIFI
- || networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET;
+ return NetworkPermissionUtil.isNetworkUnmetered(mConnectivityManager);
}
@Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java b/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java
index 7d9b699..a58990d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/crash/MinidumpUploadService.java
@@ -105,7 +105,6 @@
new JobInfo
.Builder(TaskIds.CHROME_MINIDUMP_UPLOADING_JOB_ID,
new ComponentName(context, ChromeMinidumpUploadJobService.class))
- .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setExtras(permissions);
MinidumpUploadJobService.scheduleUpload(context, builder);
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManager.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManager.java
index 3b0e921..7572865 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManager.java
@@ -17,6 +17,7 @@
import org.chromium.chrome.browser.physicalweb.PhysicalWeb;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.components.minidump_uploader.util.CrashReportingPermissionManager;
+import org.chromium.components.minidump_uploader.util.NetworkPermissionUtil;
/**
* Reads, writes, and migrates preferences related to network usage and privacy.
@@ -184,24 +185,13 @@
sharedPreferencesEditor.apply();
}
- private NetworkInfo getActiveNetworkInfo() {
+ protected boolean isNetworkAvailable() {
ConnectivityManager connectivityManager =
(ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
- return connectivityManager.getActiveNetworkInfo();
- }
-
- protected boolean isNetworkAvailable() {
- NetworkInfo networkInfo = getActiveNetworkInfo();
+ NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
return (networkInfo != null && networkInfo.isConnected());
}
- protected boolean isWiFiOrEthernetNetwork() {
- NetworkInfo networkInfo = getActiveNetworkInfo();
- return networkInfo != null
- && (networkInfo.getType() == ConnectivityManager.TYPE_WIFI
- || networkInfo.getType() == ConnectivityManager.TYPE_ETHERNET);
- }
-
protected boolean isMobileNetworkCapable() {
ConnectivityManager connectivityManager =
(ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
@@ -274,7 +264,9 @@
*/
@Override
public boolean isNetworkAvailableForCrashUploads() {
- return isNetworkAvailable() && isWiFiOrEthernetNetwork();
+ ConnectivityManager connectivityManager =
+ (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
+ return NetworkPermissionUtil.isNetworkUnmetered(connectivityManager);
}
/**
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index 622b432..af83c832 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -1477,7 +1477,6 @@
"javatests/src/org/chromium/chrome/browser/preferences/datareduction/DataReductionPromoUtilsTest.java",
"javatests/src/org/chromium/chrome/browser/preferences/password/SavePasswordsPreferencesTest.java",
"javatests/src/org/chromium/chrome/browser/preferences/privacy/ClearBrowsingDataPreferencesTest.java",
- "javatests/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManagerTest.java",
"javatests/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManagerNativeTest.java",
"javatests/src/org/chromium/chrome/browser/preferences/website/ManageSpaceActivityTest.java",
"javatests/src/org/chromium/chrome/browser/preferences/website/SiteSettingsPreferencesTest.java",
@@ -1634,6 +1633,7 @@
"junit/src/org/chromium/chrome/browser/physicalweb/PwsClientImplTest.java",
"junit/src/org/chromium/chrome/browser/physicalweb/PwsResultTest.java",
"junit/src/org/chromium/chrome/browser/physicalweb/UrlInfoTest.java",
+ "junit/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManagerTest.java",
"junit/src/org/chromium/chrome/browser/snackbar/SnackbarCollectionUnitTest.java",
"junit/src/org/chromium/chrome/browser/suggestions/TileGroupTest.java",
"junit/src/org/chromium/chrome/browser/suggestions/TileTest.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManagerTest.java
deleted file mode 100644
index 6e19851..0000000
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManagerTest.java
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.preferences.privacy;
-
-import android.content.Context;
-import android.support.test.filters.SmallTest;
-import android.test.InstrumentationTestCase;
-import android.test.UiThreadTest;
-
-import org.chromium.base.CommandLine;
-import org.chromium.base.ContextUtils;
-import org.chromium.base.test.util.AdvancedMockContext;
-import org.chromium.base.test.util.Feature;
-
-/**
- * Tests "Usage and Crash reporting" preferences.
- */
-public class PrivacyPreferencesManagerTest extends InstrumentationTestCase {
-
- private static final boolean CONNECTED = true;
- private static final boolean DISCONNECTED = false;
-
- private static final boolean WIFI_ON = true;
- private static final boolean WIFI_OFF = false;
-
- private static final boolean METRICS_UPLOAD_OK = true;
- private static final boolean METRICS_UPLOAD_NOT_PERMITTED = false;
-
- private static final boolean CRASH_NETWORK_OK = true;
- private static final boolean CRASH_NETWORK_NOT_PERMITTED = false;
-
- private static final boolean METRIC_REPORTING_ENABLED = true;
- private static final boolean METRIC_REPORTING_DISABLED = false;
-
- // Perform the same test a few times to make sure any sort of
- // caching still works.
- private static final int REPS = 3;
-
- @SmallTest
- @Feature({"Android-AppBase"})
- @UiThreadTest
- public void testAllowCrashDumpUploadNowCellDev() {
- CommandLine.init(null);
- runTest(CONNECTED, WIFI_ON, METRIC_REPORTING_ENABLED, METRICS_UPLOAD_OK, CRASH_NETWORK_OK);
- runTest(CONNECTED, WIFI_OFF, METRIC_REPORTING_ENABLED, METRICS_UPLOAD_OK,
- CRASH_NETWORK_NOT_PERMITTED);
- runTest(DISCONNECTED, WIFI_OFF, METRIC_REPORTING_ENABLED, METRICS_UPLOAD_NOT_PERMITTED,
- CRASH_NETWORK_NOT_PERMITTED);
-
- runTest(CONNECTED, WIFI_ON, METRIC_REPORTING_DISABLED, METRICS_UPLOAD_NOT_PERMITTED,
- CRASH_NETWORK_OK);
- runTest(CONNECTED, WIFI_OFF, METRIC_REPORTING_DISABLED, METRICS_UPLOAD_NOT_PERMITTED,
- CRASH_NETWORK_NOT_PERMITTED);
- runTest(DISCONNECTED, WIFI_OFF, METRIC_REPORTING_DISABLED, METRICS_UPLOAD_NOT_PERMITTED,
- CRASH_NETWORK_NOT_PERMITTED);
- }
-
- private void runTest(boolean isConnected, boolean wifiOn, boolean isMetricsReportingEnabled,
- boolean expectedMetricsUploadPermitted,
- boolean expectedNetworkAvailableForCrashUploads) {
- PermissionContext context = new PermissionContext(getInstrumentation().getTargetContext());
- ContextUtils.initApplicationContextForTests(context.getApplicationContext());
- PrivacyPreferencesManager preferenceManager = new MockPrivacyPreferencesManager(
- context, isConnected, wifiOn, isMetricsReportingEnabled);
-
- for (int i = 0; i < REPS; i++) {
- String state = String.format("[connected = %b, wifi = %b, reporting = %b]", isConnected,
- wifiOn, isMetricsReportingEnabled);
- String msg = String.format("Metrics reporting should be %1$b for %2$s",
- expectedMetricsUploadPermitted, state);
- assertEquals(msg, expectedMetricsUploadPermitted,
- preferenceManager.isMetricsUploadPermitted());
-
- msg = String.format("Crash reporting should be %1$b for wifi %2$s",
- expectedNetworkAvailableForCrashUploads, wifiOn);
- assertEquals(msg, expectedNetworkAvailableForCrashUploads,
- preferenceManager.isNetworkAvailableForCrashUploads());
- }
- }
-
- private static class MockPrivacyPreferencesManager extends PrivacyPreferencesManager {
- private final boolean mIsConnected;
- private final boolean mIsWifi;
-
- MockPrivacyPreferencesManager(Context context, boolean isConnected, boolean isWifi,
- boolean isMetricsReportingEnabled) {
- super(context);
- mIsConnected = isConnected;
- mIsWifi = isWifi;
-
- setUsageAndCrashReporting(isMetricsReportingEnabled);
- }
-
- @Override
- public boolean isNetworkAvailable() {
- return mIsConnected;
- }
-
- @Override
- public boolean isWiFiOrEthernetNetwork() {
- return mIsWifi;
- }
- }
-
- private static class PermissionContext extends AdvancedMockContext {
- public PermissionContext(Context targetContext) {
- super(targetContext);
- }
-
- @Override
- public Object getSystemService(String name) {
- if (Context.CONNECTIVITY_SERVICE.equals(name)) {
- return null;
- }
- fail("Should not ask for any other service than the ConnectionManager.");
- return super.getSystemService(name);
- }
- }
-}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManagerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManagerTest.java
new file mode 100644
index 0000000..f64216f
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/preferences/privacy/PrivacyPreferencesManagerTest.java
@@ -0,0 +1,111 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.preferences.privacy;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.CommandLine;
+import org.chromium.base.ContextUtils;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+
+/**
+ * junit tests for {@link PrivacyPreferencesManager}'s handling of "Usage and Crash reporting"
+ * preferences.
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class PrivacyPreferencesManagerTest {
+ // Parameters to simulate user- and network-permission state.
+ private static final boolean CONNECTED = true;
+ private static final boolean DISCONNECTED = false;
+
+ private static final boolean METERED = true;
+ private static final boolean UNMETERED = false;
+
+ private static final boolean METRICS_REPORTING_ENABLED = true;
+ private static final boolean METRICS_REPORTING_DISABLED = false;
+
+ // Used to set test expectations.
+ private static final boolean METRICS_UPLOAD_PERMITTED = true;
+ private static final boolean METRICS_UPLOAD_NOT_PERMITTED = false;
+
+ private static final boolean CRASH_NETWORK_AVAILABLE = true;
+ private static final boolean CRASH_NETWORK_UNAVAILABLE = false;
+
+ @Test
+ public void testUsageAndCrashReportingAccessors() {
+ CommandLine.init(null);
+
+ // TODO(yolandyan): Use Junit4 parameters to clean up this test structure.
+ runTest(CONNECTED, UNMETERED, METRICS_REPORTING_ENABLED, METRICS_UPLOAD_PERMITTED,
+ CRASH_NETWORK_AVAILABLE);
+ runTest(CONNECTED, METERED, METRICS_REPORTING_ENABLED, METRICS_UPLOAD_PERMITTED,
+ CRASH_NETWORK_UNAVAILABLE);
+ runTest(DISCONNECTED, UNMETERED, METRICS_REPORTING_ENABLED, METRICS_UPLOAD_NOT_PERMITTED,
+ CRASH_NETWORK_UNAVAILABLE);
+
+ runTest(CONNECTED, UNMETERED, METRICS_REPORTING_DISABLED, METRICS_UPLOAD_NOT_PERMITTED,
+ CRASH_NETWORK_AVAILABLE);
+ runTest(CONNECTED, METERED, METRICS_REPORTING_DISABLED, METRICS_UPLOAD_NOT_PERMITTED,
+ CRASH_NETWORK_UNAVAILABLE);
+ runTest(DISCONNECTED, UNMETERED, METRICS_REPORTING_DISABLED, METRICS_UPLOAD_NOT_PERMITTED,
+ CRASH_NETWORK_UNAVAILABLE);
+ }
+
+ private void runTest(boolean isConnected, boolean isMetered, boolean isMetricsReportingEnabled,
+ boolean expectedMetricsUploadPermitted,
+ boolean expectedNetworkAvailableForCrashUploads) {
+ // Mock out the network info accessors.
+ NetworkInfo networkInfo = mock(NetworkInfo.class);
+ when(networkInfo.isConnected()).thenReturn(isConnected);
+
+ ConnectivityManager connectivityManager = mock(ConnectivityManager.class);
+ when(connectivityManager.getActiveNetworkInfo()).thenReturn(networkInfo);
+ when(connectivityManager.isActiveNetworkMetered()).thenReturn(isMetered);
+
+ Context context = mock(Context.class);
+ when(context.getSystemService(Context.CONNECTIVITY_SERVICE))
+ .thenReturn(connectivityManager);
+
+ // Perform other setup.
+ ContextUtils.initApplicationContextForTests(RuntimeEnvironment.application);
+ PrivacyPreferencesManager preferenceManager = new TestPrivacyPreferencesManager(context);
+ preferenceManager.setUsageAndCrashReporting(isMetricsReportingEnabled);
+
+ // Test the usage and crash reporting permission accessors!
+ String state = String.format("[connected = %b, metered = %b, reporting = %b]", isConnected,
+ isMetered, isMetricsReportingEnabled);
+ String msg = String.format(
+ "Metrics reporting should be %1$b for %2$s", expectedMetricsUploadPermitted, state);
+ assertEquals(
+ msg, expectedMetricsUploadPermitted, preferenceManager.isMetricsUploadPermitted());
+
+ msg = String.format("Crash reporting should be %1$b for metered state %2$s",
+ expectedNetworkAvailableForCrashUploads, isMetered);
+ assertEquals(msg, expectedNetworkAvailableForCrashUploads,
+ preferenceManager.isNetworkAvailableForCrashUploads());
+ }
+
+ private static class TestPrivacyPreferencesManager extends PrivacyPreferencesManager {
+ TestPrivacyPreferencesManager(Context context) {
+ super(context);
+ }
+
+ // Stub out this call, as it could otherwise call into native code.
+ public void syncUsageAndCrashReportingPrefs() {}
+ }
+}
diff --git a/components/minidump_uploader/BUILD.gn b/components/minidump_uploader/BUILD.gn
index fd469b7b9..c017ccd3 100644
--- a/components/minidump_uploader/BUILD.gn
+++ b/components/minidump_uploader/BUILD.gn
@@ -20,6 +20,7 @@
"android/java/src/org/chromium/components/minidump_uploader/util/CrashReportingPermissionManager.java",
"android/java/src/org/chromium/components/minidump_uploader/util/HttpURLConnectionFactory.java",
"android/java/src/org/chromium/components/minidump_uploader/util/HttpURLConnectionFactoryImpl.java",
+ "android/java/src/org/chromium/components/minidump_uploader/util/NetworkPermissionUtil.java",
]
}
diff --git a/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadJobService.java b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadJobService.java
index 9e29f12..4ad29bf 100644
--- a/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadJobService.java
+++ b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/MinidumpUploadJobService.java
@@ -50,7 +50,7 @@
JobScheduler scheduler =
(JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);
JobInfo uploadJob =
- jobInfoBuilder
+ jobInfoBuilder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED)
.setBackoffCriteria(JOB_INITIAL_BACKOFF_TIME_IN_MS, JOB_BACKOFF_POLICY)
.build();
int result = scheduler.schedule(uploadJob);
diff --git a/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/util/NetworkPermissionUtil.java b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/util/NetworkPermissionUtil.java
new file mode 100644
index 0000000..829e5f4
--- /dev/null
+++ b/components/minidump_uploader/android/java/src/org/chromium/components/minidump_uploader/util/NetworkPermissionUtil.java
@@ -0,0 +1,20 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.components.minidump_uploader.util;
+
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+/**
+ * A container for determining whether it's ok to upload crash reports over the currently active
+ * network.
+ */
+public class NetworkPermissionUtil {
+ public static boolean isNetworkUnmetered(ConnectivityManager connectivityManager) {
+ NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
+ if (networkInfo == null || !networkInfo.isConnected()) return false;
+ return !connectivityManager.isActiveNetworkMetered();
+ }
+}