mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
With more information while sending logs (#2222)
* With more information while sending logs * With java docs and unit tests * Changes based on code review
This commit is contained in:
parent
5317063689
commit
2ea6bd7f65
6 changed files with 305 additions and 14 deletions
|
|
@ -1,11 +1,14 @@
|
||||||
package fr.free.nrw.commons.logging;
|
package fr.free.nrw.commons.logging;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import fr.free.nrw.commons.BuildConfig;
|
import fr.free.nrw.commons.BuildConfig;
|
||||||
import fr.free.nrw.commons.auth.SessionManager;
|
import fr.free.nrw.commons.auth.SessionManager;
|
||||||
|
import fr.free.nrw.commons.utils.DeviceInfoUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class responsible for sending logs to developers
|
* Class responsible for sending logs to developers
|
||||||
|
|
@ -16,16 +19,21 @@ public class CommonsLogSender extends LogsSender {
|
||||||
private static final String LOGS_PRIVATE_EMAIL_SUBJECT = "Commons Android App (%s) Logs";
|
private static final String LOGS_PRIVATE_EMAIL_SUBJECT = "Commons Android App (%s) Logs";
|
||||||
private static final String BETA_LOGS_PRIVATE_EMAIL_SUBJECT = "Commons Beta Android App (%s) Logs";
|
private static final String BETA_LOGS_PRIVATE_EMAIL_SUBJECT = "Commons Beta Android App (%s) Logs";
|
||||||
|
|
||||||
|
private SessionManager sessionManager;
|
||||||
|
private Context context;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CommonsLogSender(SessionManager sessionManager,
|
public CommonsLogSender(SessionManager sessionManager,
|
||||||
|
Context context,
|
||||||
@Named("isBeta") boolean isBeta) {
|
@Named("isBeta") boolean isBeta) {
|
||||||
super(sessionManager, isBeta);
|
super(sessionManager, isBeta);
|
||||||
|
|
||||||
|
this.sessionManager = sessionManager;
|
||||||
|
this.context = context;
|
||||||
this.logFileName = isBeta ? "CommonsBetaAppLogs.zip" : "CommonsAppLogs.zip";
|
this.logFileName = isBeta ? "CommonsBetaAppLogs.zip" : "CommonsAppLogs.zip";
|
||||||
String emailSubjectFormat = isBeta ? BETA_LOGS_PRIVATE_EMAIL_SUBJECT : LOGS_PRIVATE_EMAIL_SUBJECT;
|
String emailSubjectFormat = isBeta ? BETA_LOGS_PRIVATE_EMAIL_SUBJECT : LOGS_PRIVATE_EMAIL_SUBJECT;
|
||||||
String message = String.format(emailSubjectFormat, sessionManager.getUserName());
|
this.emailSubject = String.format(emailSubjectFormat, sessionManager.getUserName());
|
||||||
this.emailSubject = message;
|
this.emailBody = getExtraInfo();
|
||||||
this.emailBody = message;
|
|
||||||
this.mailTo = LOGS_PRIVATE_EMAIL;
|
this.mailTo = LOGS_PRIVATE_EMAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,8 +43,31 @@ public class CommonsLogSender extends LogsSender {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected String getExtraInfo() {
|
protected String getExtraInfo() {
|
||||||
return "App Version Name: " +
|
StringBuilder builder = new StringBuilder();
|
||||||
BuildConfig.VERSION_NAME +
|
builder.append("App Version Name: ")
|
||||||
"\n";
|
.append(BuildConfig.VERSION_NAME)
|
||||||
|
.append("\n");
|
||||||
|
|
||||||
|
builder.append("User Name: ")
|
||||||
|
.append(sessionManager.getUserName())
|
||||||
|
.append("\n");
|
||||||
|
|
||||||
|
builder.append("Network Type: ")
|
||||||
|
.append(DeviceInfoUtil.getConnectionType(context))
|
||||||
|
.append("\n");
|
||||||
|
|
||||||
|
builder.append("Device manufacturer: ")
|
||||||
|
.append(DeviceInfoUtil.getDeviceManufacturer())
|
||||||
|
.append("\n");
|
||||||
|
|
||||||
|
builder.append("Device model: ")
|
||||||
|
.append(DeviceInfoUtil.getDeviceModel())
|
||||||
|
.append("\n");
|
||||||
|
|
||||||
|
builder.append("Android Version: ")
|
||||||
|
.append(DeviceInfoUtil.getAndroidVersion())
|
||||||
|
.append("\n");
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
package fr.free.nrw.commons.utils;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.utils.model.ConnectionType;
|
||||||
|
import fr.free.nrw.commons.utils.model.NetworkConnectionType;
|
||||||
|
|
||||||
|
import static fr.free.nrw.commons.utils.model.ConnectionType.CELLULAR;
|
||||||
|
import static fr.free.nrw.commons.utils.model.ConnectionType.CELLULAR_3G;
|
||||||
|
import static fr.free.nrw.commons.utils.model.ConnectionType.CELLULAR_4G;
|
||||||
|
import static fr.free.nrw.commons.utils.model.ConnectionType.NO_INTERNET;
|
||||||
|
import static fr.free.nrw.commons.utils.model.ConnectionType.WIFI_NETWORK;
|
||||||
|
import static fr.free.nrw.commons.utils.model.NetworkConnectionType.FOUR_G;
|
||||||
|
import static fr.free.nrw.commons.utils.model.NetworkConnectionType.THREE_G;
|
||||||
|
import static fr.free.nrw.commons.utils.model.NetworkConnectionType.TWO_G;
|
||||||
|
import static fr.free.nrw.commons.utils.model.NetworkConnectionType.UNKNOWN;
|
||||||
|
import static fr.free.nrw.commons.utils.model.NetworkConnectionType.WIFI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Util class to get any information about the user's device
|
||||||
|
* Ensure that any sensitive information like IMEI is not fetched/shared without user's consent
|
||||||
|
*/
|
||||||
|
public class DeviceInfoUtil {
|
||||||
|
private static final Map<NetworkConnectionType, ConnectionType> TYPE_MAPPING = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
TYPE_MAPPING.put(TWO_G, CELLULAR);
|
||||||
|
TYPE_MAPPING.put(THREE_G, CELLULAR_3G);
|
||||||
|
TYPE_MAPPING.put(FOUR_G, CELLULAR_4G);
|
||||||
|
TYPE_MAPPING.put(WIFI, WIFI_NETWORK);
|
||||||
|
TYPE_MAPPING.put(UNKNOWN, CELLULAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get network connection type
|
||||||
|
* @param context
|
||||||
|
* @return wifi/cellular-4g/cellular-3g/cellular-2g/no-internet
|
||||||
|
*/
|
||||||
|
public static ConnectionType getConnectionType(Context context) {
|
||||||
|
if (!NetworkUtils.isInternetConnectionEstablished(context)) {
|
||||||
|
return NO_INTERNET;
|
||||||
|
}
|
||||||
|
NetworkConnectionType networkType = NetworkUtils.getNetworkType(context);
|
||||||
|
ConnectionType deviceNetworkType = TYPE_MAPPING.get(networkType);
|
||||||
|
return deviceNetworkType == null ? CELLULAR : deviceNetworkType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Device manufacturer
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getDeviceManufacturer() {
|
||||||
|
return Build.MANUFACTURER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Device model name
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getDeviceModel() {
|
||||||
|
return Build.DEVICE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get Android version. Eg. 4.4.2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getAndroidVersion() {
|
||||||
|
return Build.VERSION.RELEASE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,14 +5,18 @@ import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.utils.model.NetworkConnectionType;
|
||||||
|
|
||||||
public class NetworkUtils {
|
public class NetworkUtils {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://developer.android.com/training/monitoring-device-state/connectivity-monitoring#java
|
* https://developer.android.com/training/monitoring-device-state/connectivity-monitoring#java
|
||||||
* Check if internet connection is established.
|
* Check if internet connection is established.
|
||||||
|
*
|
||||||
* @param context context passed to this method could be null.
|
* @param context context passed to this method could be null.
|
||||||
* @return Returns current internet connection status. Returns false if null context was passed.
|
* @return Returns current internet connection status. Returns false if null context was passed.
|
||||||
*/
|
*/
|
||||||
|
|
@ -22,13 +26,65 @@ public class NetworkUtils {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectivityManager cm =
|
NetworkInfo activeNetwork = getNetworkInfo(context);
|
||||||
(ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
||||||
|
|
||||||
if (cm == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
|
|
||||||
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
|
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detect network connection type
|
||||||
|
*/
|
||||||
|
static NetworkConnectionType getNetworkType(Context context) {
|
||||||
|
TelephonyManager telephonyManager = (TelephonyManager) context.getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
|
if (telephonyManager == null) {
|
||||||
|
return NetworkConnectionType.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkInfo networkInfo = getNetworkInfo(context);
|
||||||
|
if (networkInfo == null) {
|
||||||
|
return NetworkConnectionType.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
int network = networkInfo.getType();
|
||||||
|
if (network == ConnectivityManager.TYPE_WIFI) {
|
||||||
|
return NetworkConnectionType.WIFI;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mobileNetwork = telephonyManager.getNetworkType();
|
||||||
|
switch (mobileNetwork) {
|
||||||
|
case TelephonyManager.NETWORK_TYPE_GPRS:
|
||||||
|
case TelephonyManager.NETWORK_TYPE_EDGE:
|
||||||
|
case TelephonyManager.NETWORK_TYPE_CDMA:
|
||||||
|
case TelephonyManager.NETWORK_TYPE_1xRTT:
|
||||||
|
return NetworkConnectionType.TWO_G;
|
||||||
|
case TelephonyManager.NETWORK_TYPE_HSDPA:
|
||||||
|
case TelephonyManager.NETWORK_TYPE_UMTS:
|
||||||
|
case TelephonyManager.NETWORK_TYPE_HSUPA:
|
||||||
|
case TelephonyManager.NETWORK_TYPE_HSPA:
|
||||||
|
case TelephonyManager.NETWORK_TYPE_EHRPD:
|
||||||
|
case TelephonyManager.NETWORK_TYPE_EVDO_0:
|
||||||
|
case TelephonyManager.NETWORK_TYPE_EVDO_A:
|
||||||
|
case TelephonyManager.NETWORK_TYPE_EVDO_B:
|
||||||
|
return NetworkConnectionType.THREE_G;
|
||||||
|
case TelephonyManager.NETWORK_TYPE_LTE:
|
||||||
|
case TelephonyManager.NETWORK_TYPE_HSPAP:
|
||||||
|
return NetworkConnectionType.FOUR_G;
|
||||||
|
default:
|
||||||
|
return NetworkConnectionType.UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracted private method to get nullable network info
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private static NetworkInfo getNetworkInfo(Context context) {
|
||||||
|
ConnectivityManager connectivityManager =
|
||||||
|
(ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
|
||||||
|
if (connectivityManager == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return connectivityManager.getActiveNetworkInfo();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
package fr.free.nrw.commons.utils.model;
|
||||||
|
|
||||||
|
public enum ConnectionType {
|
||||||
|
WIFI_NETWORK("wifi"), CELLULAR_4G("cellular-4g"), CELLULAR_3G("cellular-3g"), CELLULAR("cellular"), NO_INTERNET("no-internet");
|
||||||
|
|
||||||
|
private final String text;
|
||||||
|
|
||||||
|
ConnectionType(String text) {
|
||||||
|
this.text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
package fr.free.nrw.commons.utils.model;
|
||||||
|
|
||||||
|
public enum NetworkConnectionType {
|
||||||
|
WIFI, TWO_G, THREE_G, FOUR_G, UNKNOWN
|
||||||
|
}
|
||||||
|
|
@ -4,11 +4,19 @@ import android.app.Application;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.NetworkInfo;
|
import android.net.NetworkInfo;
|
||||||
|
import android.telephony.TelephonyManager;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import fr.free.nrw.commons.utils.model.NetworkConnectionType;
|
||||||
|
|
||||||
|
import static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE;
|
||||||
|
import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPA;
|
||||||
|
import static android.telephony.TelephonyManager.NETWORK_TYPE_LTE;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
|
@ -68,4 +76,104 @@ public class NetworkUtilsTest {
|
||||||
boolean internetConnectionEstablished = NetworkUtils.isInternetConnectionEstablished(mockContext);
|
boolean internetConnectionEstablished = NetworkUtils.isInternetConnectionEstablished(mockContext);
|
||||||
assertFalse(internetConnectionEstablished);
|
assertFalse(internetConnectionEstablished);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWifiNetwork() {
|
||||||
|
Context mockContext = mock(Context.class);
|
||||||
|
Application mockApplication = mock(Application.class);
|
||||||
|
ConnectivityManager mockConnectivityManager = mock(ConnectivityManager.class);
|
||||||
|
NetworkInfo mockNetworkInfo = mock(NetworkInfo.class);
|
||||||
|
when(mockNetworkInfo.getType())
|
||||||
|
.thenReturn(ConnectivityManager.TYPE_WIFI);
|
||||||
|
when(mockConnectivityManager.getActiveNetworkInfo())
|
||||||
|
.thenReturn(mockNetworkInfo);
|
||||||
|
when(mockApplication.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||||
|
.thenReturn(mockConnectivityManager);
|
||||||
|
|
||||||
|
when(mockApplication.getSystemService(Context.TELEPHONY_SERVICE))
|
||||||
|
.thenReturn(mock(TelephonyManager.class));
|
||||||
|
when(mockContext.getApplicationContext()).thenReturn(mockApplication);
|
||||||
|
|
||||||
|
NetworkConnectionType networkType = NetworkUtils.getNetworkType(mockContext);
|
||||||
|
|
||||||
|
assertEquals(networkType, NetworkConnectionType.WIFI);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCellular2GNetwork() {
|
||||||
|
Context mockContext = mock(Context.class);
|
||||||
|
Application mockApplication = mock(Application.class);
|
||||||
|
ConnectivityManager mockConnectivityManager = mock(ConnectivityManager.class);
|
||||||
|
NetworkInfo mockNetworkInfo = mock(NetworkInfo.class);
|
||||||
|
when(mockNetworkInfo.getType())
|
||||||
|
.thenReturn(ConnectivityManager.TYPE_MOBILE);
|
||||||
|
when(mockConnectivityManager.getActiveNetworkInfo())
|
||||||
|
.thenReturn(mockNetworkInfo);
|
||||||
|
when(mockApplication.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||||
|
.thenReturn(mockConnectivityManager);
|
||||||
|
|
||||||
|
TelephonyManager mockTelephonyManager = mock(TelephonyManager.class);
|
||||||
|
when(mockTelephonyManager.getNetworkType())
|
||||||
|
.thenReturn(NETWORK_TYPE_EDGE);
|
||||||
|
|
||||||
|
when(mockApplication.getSystemService(Context.TELEPHONY_SERVICE))
|
||||||
|
.thenReturn(mockTelephonyManager);
|
||||||
|
when(mockContext.getApplicationContext()).thenReturn(mockApplication);
|
||||||
|
|
||||||
|
NetworkConnectionType networkType = NetworkUtils.getNetworkType(mockContext);
|
||||||
|
|
||||||
|
assertEquals(networkType, NetworkConnectionType.TWO_G);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCellular3GNetwork() {
|
||||||
|
Context mockContext = mock(Context.class);
|
||||||
|
Application mockApplication = mock(Application.class);
|
||||||
|
ConnectivityManager mockConnectivityManager = mock(ConnectivityManager.class);
|
||||||
|
NetworkInfo mockNetworkInfo = mock(NetworkInfo.class);
|
||||||
|
when(mockNetworkInfo.getType())
|
||||||
|
.thenReturn(ConnectivityManager.TYPE_MOBILE);
|
||||||
|
when(mockConnectivityManager.getActiveNetworkInfo())
|
||||||
|
.thenReturn(mockNetworkInfo);
|
||||||
|
when(mockApplication.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||||
|
.thenReturn(mockConnectivityManager);
|
||||||
|
|
||||||
|
TelephonyManager mockTelephonyManager = mock(TelephonyManager.class);
|
||||||
|
when(mockTelephonyManager.getNetworkType())
|
||||||
|
.thenReturn(NETWORK_TYPE_HSPA);
|
||||||
|
|
||||||
|
when(mockApplication.getSystemService(Context.TELEPHONY_SERVICE))
|
||||||
|
.thenReturn(mockTelephonyManager);
|
||||||
|
when(mockContext.getApplicationContext()).thenReturn(mockApplication);
|
||||||
|
|
||||||
|
NetworkConnectionType networkType = NetworkUtils.getNetworkType(mockContext);
|
||||||
|
|
||||||
|
assertEquals(networkType, NetworkConnectionType.THREE_G);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCellular4GNetwork() {
|
||||||
|
Context mockContext = mock(Context.class);
|
||||||
|
Application mockApplication = mock(Application.class);
|
||||||
|
ConnectivityManager mockConnectivityManager = mock(ConnectivityManager.class);
|
||||||
|
NetworkInfo mockNetworkInfo = mock(NetworkInfo.class);
|
||||||
|
when(mockNetworkInfo.getType())
|
||||||
|
.thenReturn(ConnectivityManager.TYPE_MOBILE);
|
||||||
|
when(mockConnectivityManager.getActiveNetworkInfo())
|
||||||
|
.thenReturn(mockNetworkInfo);
|
||||||
|
when(mockApplication.getSystemService(Context.CONNECTIVITY_SERVICE))
|
||||||
|
.thenReturn(mockConnectivityManager);
|
||||||
|
|
||||||
|
TelephonyManager mockTelephonyManager = mock(TelephonyManager.class);
|
||||||
|
when(mockTelephonyManager.getNetworkType())
|
||||||
|
.thenReturn(NETWORK_TYPE_LTE);
|
||||||
|
|
||||||
|
when(mockApplication.getSystemService(Context.TELEPHONY_SERVICE))
|
||||||
|
.thenReturn(mockTelephonyManager);
|
||||||
|
when(mockContext.getApplicationContext()).thenReturn(mockApplication);
|
||||||
|
|
||||||
|
NetworkConnectionType networkType = NetworkUtils.getNetworkType(mockContext);
|
||||||
|
|
||||||
|
assertEquals(networkType, NetworkConnectionType.FOUR_G);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue