Merge commit '88932754ffdcbffb3cb43e03991e5eb598c10458' into nyc-mr1-dev-plus-aosp

* commit '88932754ffdcbffb3cb43e03991e5eb598c10458':
  Captive portals: login activity probes like NetworkMonitor
  Logging improvements in CaptivePortalLoginActivity
  Captive portal systel log improvements
  Fix flaky IpPrefixTest.
  Removing bogus file added by mistake
  frameworks-test: adding missing @SmallTest
  Netd events: record connect() success/errno
  Add missing dependency.
  Show notification for always-on app VPN
This commit is contained in:
The Android Automerger
2017-01-27 06:39:52 +00:00
20 changed files with 320 additions and 132 deletions

12
]
View File

@@ -1,12 +0,0 @@
NetworkNotificationManager: logging improvements
TODO: squash me
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch notification_tagging
# Your branch is ahead of 'goog/master' by 2 commits.
# (use "git push" to publish your local commits)
#
# Changes to be committed:
# modified: services/core/java/com/android/server/connectivity/NetworkNotificationManager.java
#

View File

@@ -229,6 +229,13 @@ public class ConnectivityManager {
*/ */
public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL"; public static final String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
/**
* Key for passing a user agent string to the captive portal login activity.
* {@hide}
*/
public static final String EXTRA_CAPTIVE_PORTAL_USER_AGENT =
"android.net.extra.CAPTIVE_PORTAL_USER_AGENT";
/** /**
* Broadcast action to indicate the change of data activity status * Broadcast action to indicate the change of data activity status
* (idle or active) on a network in a recent period. * (idle or active) on a network in a recent period.

View File

@@ -18,14 +18,14 @@ package android.net;
import android.net.IpPrefix; import android.net.IpPrefix;
import android.os.Parcel; import android.os.Parcel;
import static android.test.MoreAsserts.assertNotEqual;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import static org.junit.Assert.assertArrayEquals;
import java.net.InetAddress; import java.net.InetAddress;
import java.util.Random; import java.util.Random;
import junit.framework.TestCase; import junit.framework.TestCase;
import static android.test.MoreAsserts.assertNotEqual;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
public class IpPrefixTest extends TestCase { public class IpPrefixTest extends TestCase {
@@ -242,25 +242,42 @@ public class IpPrefixTest extends TestCase {
@SmallTest @SmallTest
public void testHashCode() { public void testHashCode() {
IpPrefix p; IpPrefix p = new IpPrefix(new byte[4], 0);
int oldCode = -1;
Random random = new Random(); Random random = new Random();
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
final IpPrefix oldP = p;
if (random.nextBoolean()) { if (random.nextBoolean()) {
// IPv4. // IPv4.
byte[] b = new byte[4]; byte[] b = new byte[4];
random.nextBytes(b); random.nextBytes(b);
p = new IpPrefix(b, random.nextInt(33)); p = new IpPrefix(b, random.nextInt(33));
assertNotEqual(oldCode, p.hashCode());
oldCode = p.hashCode();
} else { } else {
// IPv6. // IPv6.
byte[] b = new byte[16]; byte[] b = new byte[16];
random.nextBytes(b); random.nextBytes(b);
p = new IpPrefix(b, random.nextInt(129)); p = new IpPrefix(b, random.nextInt(129));
assertNotEqual(oldCode, p.hashCode());
oldCode = p.hashCode();
} }
if (p.equals(oldP)) {
assertEquals(p.hashCode(), oldP.hashCode());
}
if (p.hashCode() != oldP.hashCode()) {
assertNotEqual(p, oldP);
}
}
}
@SmallTest
public void testHashCodeIsNotConstant() {
IpPrefix[] prefixes = {
new IpPrefix("2001:db8:f00::ace:d00d/127"),
new IpPrefix("192.0.2.0/23"),
new IpPrefix("::/0"),
new IpPrefix("0.0.0.0/0"),
};
for (int i = 0; i < prefixes.length; i++) {
for (int j = i + 1; j < prefixes.length; j++) {
assertNotEqual(prefixes[i].hashCode(), prefixes[j].hashCode());
}
} }
} }

View File

@@ -55,12 +55,15 @@ import java.lang.reflect.Method;
import java.util.Random; import java.util.Random;
public class CaptivePortalLoginActivity extends Activity { public class CaptivePortalLoginActivity extends Activity {
private static final String TAG = "CaptivePortalLogin"; private static final String TAG = CaptivePortalLoginActivity.class.getSimpleName();
private static final boolean DBG = true;
private static final int SOCKET_TIMEOUT_MS = 10000; private static final int SOCKET_TIMEOUT_MS = 10000;
private enum Result { DISMISSED, UNWANTED, WANTED_AS_IS }; private enum Result { DISMISSED, UNWANTED, WANTED_AS_IS };
private URL mURL; private URL mUrl;
private String mUserAgent;
private Network mNetwork; private Network mNetwork;
private CaptivePortal mCaptivePortal; private CaptivePortal mCaptivePortal;
private NetworkCallback mNetworkCallback; private NetworkCallback mNetworkCallback;
@@ -72,17 +75,20 @@ public class CaptivePortalLoginActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mCm = ConnectivityManager.from(this); mCm = ConnectivityManager.from(this);
String url = getIntent().getStringExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL);
if (url == null) url = mCm.getCaptivePortalServerUrl();
try {
mURL = new URL(url);
} catch (MalformedURLException e) {
// System misconfigured, bail out in a way that at least provides network access.
Log.e(TAG, "Invalid captive portal URL, url=" + url);
done(Result.WANTED_AS_IS);
}
mNetwork = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_NETWORK); mNetwork = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_NETWORK);
mCaptivePortal = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL); mCaptivePortal = getIntent().getParcelableExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL);
mUserAgent = getIntent().getParcelableExtra(
ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT);
mUrl = getUrl();
if (mUrl == null) {
// getUrl() failed to parse the url provided in the intent: bail out in a way that
// at least provides network access.
done(Result.WANTED_AS_IS);
return;
}
if (DBG) {
Log.d(TAG, String.format("onCreate for %s", mUrl.toString()));
}
// Also initializes proxy system properties. // Also initializes proxy system properties.
mCm.bindProcessToNetwork(mNetwork); mCm.bindProcessToNetwork(mNetwork);
@@ -149,6 +155,9 @@ public class CaptivePortalLoginActivity extends Activity {
} }
private void done(Result result) { private void done(Result result) {
if (DBG) {
Log.d(TAG, String.format("Result %s for %s", result.name(), mUrl.toString()));
}
if (mNetworkCallback != null) { if (mNetworkCallback != null) {
mCm.unregisterNetworkCallback(mNetworkCallback); mCm.unregisterNetworkCallback(mNetworkCallback);
mNetworkCallback = null; mNetworkCallback = null;
@@ -185,22 +194,31 @@ public class CaptivePortalLoginActivity extends Activity {
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId(); final Result result;
if (id == R.id.action_use_network) { final String action;
done(Result.WANTED_AS_IS); final int id = item.getItemId();
return true; switch (id) {
case R.id.action_use_network:
result = Result.WANTED_AS_IS;
action = "USE_NETWORK";
break;
case R.id.action_do_not_use_network:
result = Result.UNWANTED;
action = "DO_NOT_USE_NETWORK";
break;
default:
return super.onOptionsItemSelected(item);
} }
if (id == R.id.action_do_not_use_network) { if (DBG) {
done(Result.UNWANTED); Log.d(TAG, String.format("onOptionsItemSelect %s for %s", action, mUrl.toString()));
return true;
} }
return super.onOptionsItemSelected(item); done(result);
return true;
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
if (mNetworkCallback != null) { if (mNetworkCallback != null) {
mCm.unregisterNetworkCallback(mNetworkCallback); mCm.unregisterNetworkCallback(mNetworkCallback);
mNetworkCallback = null; mNetworkCallback = null;
@@ -215,11 +233,29 @@ public class CaptivePortalLoginActivity extends Activity {
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(mURL.toString()))); final String url = mUrl.toString();
if (DBG) {
Log.d(TAG, "starting activity with intent ACTION_VIEW for " + url);
}
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
} }
} }
private URL getUrl() {
String url = getIntent().getStringExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL);
if (url == null) {
url = mCm.getCaptivePortalServerUrl();
}
try {
return new URL(url);
} catch (MalformedURLException e) {
Log.e(TAG, "Invalid captive portal URL " + url);
}
return null;
}
private void testForCaptivePortal() { private void testForCaptivePortal() {
// TODO: reuse NetworkMonitor facilities for consistent captive portal detection.
new Thread(new Runnable() { new Thread(new Runnable() {
public void run() { public void run() {
// Give time for captive portal to open. // Give time for captive portal to open.
@@ -230,11 +266,14 @@ public class CaptivePortalLoginActivity extends Activity {
HttpURLConnection urlConnection = null; HttpURLConnection urlConnection = null;
int httpResponseCode = 500; int httpResponseCode = 500;
try { try {
urlConnection = (HttpURLConnection) mURL.openConnection(); urlConnection = (HttpURLConnection) mNetwork.openConnection(mUrl);
urlConnection.setInstanceFollowRedirects(false); urlConnection.setInstanceFollowRedirects(false);
urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS); urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS); urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
urlConnection.setUseCaches(false); urlConnection.setUseCaches(false);
if (mUserAgent != null) {
urlConnection.setRequestProperty("User-Agent", mUserAgent);
}
urlConnection.getInputStream(); urlConnection.getInputStream();
httpResponseCode = urlConnection.getResponseCode(); httpResponseCode = urlConnection.getResponseCode();
} catch (IOException e) { } catch (IOException e) {
@@ -292,7 +331,7 @@ public class CaptivePortalLoginActivity extends Activity {
// settings. Now prompt the WebView read the Network-specific proxy settings. // settings. Now prompt the WebView read the Network-specific proxy settings.
setWebViewProxy(); setWebViewProxy();
// Load the real page. // Load the real page.
view.loadUrl(mURL.toString()); view.loadUrl(mUrl.toString());
return; return;
} else if (mPagesLoaded == 2) { } else if (mPagesLoaded == 2) {
// Prevent going back to empty first page. // Prevent going back to empty first page.

View File

@@ -24,6 +24,7 @@ import android.net.NetworkRequest;
import android.net.metrics.DnsEvent; import android.net.metrics.DnsEvent;
import android.net.metrics.INetdEventListener; import android.net.metrics.INetdEventListener;
import android.net.metrics.IpConnectivityLog; import android.net.metrics.IpConnectivityLog;
import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
@@ -44,7 +45,7 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
public static final String SERVICE_NAME = "netd_listener"; public static final String SERVICE_NAME = "netd_listener";
private static final String TAG = NetdEventListenerService.class.getSimpleName(); private static final String TAG = NetdEventListenerService.class.getSimpleName();
private static final boolean DBG = true; private static final boolean DBG = false;
private static final boolean VDBG = false; private static final boolean VDBG = false;
// TODO: read this constant from system property // TODO: read this constant from system property
@@ -86,7 +87,7 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
byte[] returnCodes = Arrays.copyOf(mReturnCodes, mEventCount); byte[] returnCodes = Arrays.copyOf(mReturnCodes, mEventCount);
int[] latenciesMs = Arrays.copyOf(mLatenciesMs, mEventCount); int[] latenciesMs = Arrays.copyOf(mLatenciesMs, mEventCount);
mMetricsLog.log(new DnsEvent(mNetId, eventTypes, returnCodes, latenciesMs)); mMetricsLog.log(new DnsEvent(mNetId, eventTypes, returnCodes, latenciesMs));
maybeLog(String.format("Logging %d results for netId %d", mEventCount, mNetId)); maybeLog("Logging %d results for netId %d", mEventCount, mNetId);
mEventCount = 0; mEventCount = 0;
} }
@@ -136,9 +137,9 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
// Called concurrently by multiple binder threads. // Called concurrently by multiple binder threads.
// This method must not block or perform long-running operations. // This method must not block or perform long-running operations.
public synchronized void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs, public synchronized void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs,
String hostname, String[] ipAddresses, int ipAddressesCount, int uid) { String hostname, String[] ipAddresses, int ipAddressesCount, int uid)
maybeVerboseLog(String.format("onDnsEvent(%d, %d, %d, %d)", throws RemoteException {
netId, eventType, returnCode, latencyMs)); maybeVerboseLog("onDnsEvent(%d, %d, %d, %dms)", netId, eventType, returnCode, latencyMs);
DnsEventBatch batch = mEventBatches.get(netId); DnsEventBatch batch = mEventBatches.get(netId);
if (batch == null) { if (batch == null) {
@@ -151,9 +152,9 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
@Override @Override
// Called concurrently by multiple binder threads. // Called concurrently by multiple binder threads.
// This method must not block or perform long-running operations. // This method must not block or perform long-running operations.
public synchronized void onConnectEvent(int netId, int latencyMs, String ipAddr, int port, public synchronized void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port,
int uid) { int uid) throws RemoteException {
maybeVerboseLog(String.format("onConnectEvent(%d, %d)", netId, latencyMs)); maybeVerboseLog("onConnectEvent(%d, %d, %dms)", netId, error, latencyMs);
} }
public synchronized void dump(PrintWriter writer) { public synchronized void dump(PrintWriter writer) {
@@ -166,11 +167,11 @@ public class NetdEventListenerService extends INetdEventListener.Stub {
pw.decreaseIndent(); pw.decreaseIndent();
} }
private static void maybeLog(String s) { private static void maybeLog(String s, Object... args) {
if (DBG) Log.d(TAG, s); if (DBG) Log.d(TAG, String.format(s, args));
} }
private static void maybeVerboseLog(String s) { private static void maybeVerboseLog(String s, Object... args) {
if (VDBG) Log.d(TAG, s); if (VDBG) Log.d(TAG, String.format(s, args));
} }
} }

View File

@@ -80,7 +80,8 @@ import java.util.concurrent.TimeUnit;
*/ */
public class NetworkMonitor extends StateMachine { public class NetworkMonitor extends StateMachine {
private static final String TAG = NetworkMonitor.class.getSimpleName(); private static final String TAG = NetworkMonitor.class.getSimpleName();
private static final boolean DBG = false; private static final boolean DBG = true;
private static final boolean VDBG = false;
// Default configuration values for captive portal detection probes. // Default configuration values for captive portal detection probes.
// TODO: append a random length parameter to the default HTTPS url. // TODO: append a random length parameter to the default HTTPS url.
@@ -432,6 +433,8 @@ public class NetworkMonitor extends StateMachine {
})); }));
intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL, intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL,
mLastPortalProbeResult.detectUrl); mLastPortalProbeResult.detectUrl);
intent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_USER_AGENT,
getCaptivePortalUserAgent(mContext));
intent.setFlags( intent.setFlags(
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK); Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivityAsUser(intent, UserHandle.CURRENT); mContext.startActivityAsUser(intent, UserHandle.CURRENT);
@@ -954,7 +957,7 @@ public class NetworkMonitor extends StateMachine {
latencyBroadcast.putExtra(EXTRA_SSID, currentWifiInfo.getSSID()); latencyBroadcast.putExtra(EXTRA_SSID, currentWifiInfo.getSSID());
latencyBroadcast.putExtra(EXTRA_BSSID, currentWifiInfo.getBSSID()); latencyBroadcast.putExtra(EXTRA_BSSID, currentWifiInfo.getBSSID());
} else { } else {
if (DBG) logw("network info is TYPE_WIFI but no ConnectionInfo found"); if (VDBG) logw("network info is TYPE_WIFI but no ConnectionInfo found");
return; return;
} }
break; break;
@@ -967,8 +970,8 @@ public class NetworkMonitor extends StateMachine {
if (cellInfo.isRegistered()) { if (cellInfo.isRegistered()) {
numRegisteredCellInfo++; numRegisteredCellInfo++;
if (numRegisteredCellInfo > 1) { if (numRegisteredCellInfo > 1) {
log("more than one registered CellInfo. Can't " + if (VDBG) logw("more than one registered CellInfo." +
"tell which is active. Bailing."); " Can't tell which is active. Bailing.");
return; return;
} }
if (cellInfo instanceof CellInfoCdma) { if (cellInfo instanceof CellInfoCdma) {
@@ -984,7 +987,7 @@ public class NetworkMonitor extends StateMachine {
CellIdentityWcdma cellId = ((CellInfoWcdma) cellInfo).getCellIdentity(); CellIdentityWcdma cellId = ((CellInfoWcdma) cellInfo).getCellIdentity();
latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId); latencyBroadcast.putExtra(EXTRA_CELL_ID, cellId);
} else { } else {
if (DBG) logw("Registered cellinfo is unrecognized"); if (VDBG) logw("Registered cellinfo is unrecognized");
return; return;
} }
} }

View File

@@ -114,7 +114,7 @@ public class NetworkNotificationManager {
} }
if (DBG) { if (DBG) {
Slog.d(TAG, "showNotification " + notifyType Slog.d(TAG, "showNotification id=" + id + " " + notifyType
+ " transportType=" + getTransportName(transportType) + " transportType=" + getTransportName(transportType)
+ " extraInfo=" + extraInfo + " highPriority=" + highPriority); + " extraInfo=" + extraInfo + " highPriority=" + highPriority);
} }
@@ -187,7 +187,7 @@ public class NetworkNotificationManager {
try { try {
mNotificationManager.notifyAsUser(NOTIFICATION_ID, id, notification, UserHandle.ALL); mNotificationManager.notifyAsUser(NOTIFICATION_ID, id, notification, UserHandle.ALL);
} catch (NullPointerException npe) { } catch (NullPointerException npe) {
Slog.d(TAG, "setNotificationVisible: visible notificationManager npe=" + npe); Slog.d(TAG, "setNotificationVisible: visible notificationManager error", npe);
} }
} }
@@ -198,7 +198,7 @@ public class NetworkNotificationManager {
try { try {
mNotificationManager.cancelAsUser(NOTIFICATION_ID, id, UserHandle.ALL); mNotificationManager.cancelAsUser(NOTIFICATION_ID, id, UserHandle.ALL);
} catch (NullPointerException npe) { } catch (NullPointerException npe) {
Slog.d(TAG, "setNotificationVisible: cancel notificationManager npe=" + npe); Slog.d(TAG, "setNotificationVisible: cancel notificationManager error", npe);
} }
} }

View File

@@ -27,6 +27,8 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
import android.app.AppGlobals; import android.app.AppGlobals;
import android.app.AppOpsManager; import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent; import android.app.PendingIntent;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName; import android.content.ComponentName;
@@ -76,6 +78,7 @@ import android.text.TextUtils;
import android.util.ArraySet; import android.util.ArraySet;
import android.util.Log; import android.util.Log;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.net.LegacyVpnInfo; import com.android.internal.net.LegacyVpnInfo;
@@ -241,12 +244,14 @@ public class Vpn {
/** /**
* Update current state, dispaching event to listeners. * Update current state, dispaching event to listeners.
*/ */
private void updateState(DetailedState detailedState, String reason) { @VisibleForTesting
protected void updateState(DetailedState detailedState, String reason) {
if (LOGD) Log.d(TAG, "setting state=" + detailedState + ", reason=" + reason); if (LOGD) Log.d(TAG, "setting state=" + detailedState + ", reason=" + reason);
mNetworkInfo.setDetailedState(detailedState, reason, null); mNetworkInfo.setDetailedState(detailedState, reason, null);
if (mNetworkAgent != null) { if (mNetworkAgent != null) {
mNetworkAgent.sendNetworkInfo(mNetworkInfo); mNetworkAgent.sendNetworkInfo(mNetworkInfo);
} }
updateAlwaysOnNotification(detailedState);
} }
/** /**
@@ -280,7 +285,10 @@ public class Vpn {
} }
mLockdown = (mAlwaysOn && lockdown); mLockdown = (mAlwaysOn && lockdown);
if (!isCurrentPreparedPackage(packageName)) { if (isCurrentPreparedPackage(packageName)) {
updateAlwaysOnNotification(mNetworkInfo.getDetailedState());
} else {
// Prepare this app. The notification will update as a side-effect of updateState().
prepareInternal(packageName); prepareInternal(packageName);
} }
maybeRegisterPackageChangeReceiverLocked(packageName); maybeRegisterPackageChangeReceiverLocked(packageName);
@@ -682,22 +690,19 @@ public class Vpn {
} }
} }
private void agentDisconnect(NetworkInfo networkInfo, NetworkAgent networkAgent) { private void agentDisconnect(NetworkAgent networkAgent) {
networkInfo.setIsAvailable(false);
networkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
if (networkAgent != null) { if (networkAgent != null) {
NetworkInfo networkInfo = new NetworkInfo(mNetworkInfo);
networkInfo.setIsAvailable(false);
networkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null);
networkAgent.sendNetworkInfo(networkInfo); networkAgent.sendNetworkInfo(networkInfo);
} }
} }
private void agentDisconnect(NetworkAgent networkAgent) {
NetworkInfo networkInfo = new NetworkInfo(mNetworkInfo);
agentDisconnect(networkInfo, networkAgent);
}
private void agentDisconnect() { private void agentDisconnect() {
if (mNetworkInfo.isConnected()) { if (mNetworkInfo.isConnected()) {
agentDisconnect(mNetworkInfo, mNetworkAgent); mNetworkInfo.setIsAvailable(false);
updateState(DetailedState.DISCONNECTED, "agentDisconnect");
mNetworkAgent = null; mNetworkAgent = null;
} }
} }
@@ -1250,6 +1255,43 @@ public class Vpn {
} }
} }
private void updateAlwaysOnNotification(DetailedState networkState) {
final boolean visible = (mAlwaysOn && networkState != DetailedState.CONNECTED);
updateAlwaysOnNotificationInternal(visible);
}
@VisibleForTesting
protected void updateAlwaysOnNotificationInternal(boolean visible) {
final UserHandle user = UserHandle.of(mUserHandle);
final long token = Binder.clearCallingIdentity();
try {
final NotificationManager notificationManager = NotificationManager.from(mContext);
if (!visible) {
notificationManager.cancelAsUser(TAG, 0, user);
return;
}
final Intent intent = new Intent(Settings.ACTION_VPN_SETTINGS);
final PendingIntent configIntent = PendingIntent.getActivityAsUser(
mContext, /* request */ 0, intent,
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT,
null, user);
final Notification.Builder builder = new Notification.Builder(mContext)
.setDefaults(0)
.setSmallIcon(R.drawable.vpn_connected)
.setContentTitle(mContext.getString(R.string.vpn_lockdown_disconnected))
.setContentText(mContext.getString(R.string.vpn_lockdown_config))
.setContentIntent(configIntent)
.setCategory(Notification.CATEGORY_SYSTEM)
.setPriority(Notification.PRIORITY_LOW)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setOngoing(true)
.setColor(mContext.getColor(R.color.system_notification_accent_color));
notificationManager.notifyAsUser(TAG, 0, builder.build(), user);
} finally {
Binder.restoreCallingIdentity(token);
}
}
private native int jniCreate(int mtu); private native int jniCreate(int mtu);
private native String jniGetName(int tun); private native String jniGetName(int tun);
private native int jniSetAddresses(String interfaze, String addresses); private native int jniSetAddresses(String interfaze, String addresses);

View File

@@ -12,6 +12,7 @@ LOCAL_MODULE_TAGS := tests
LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_STATIC_JAVA_LIBRARIES := \ LOCAL_STATIC_JAVA_LIBRARIES := \
easymocklib \
frameworks-base-testutils \ frameworks-base-testutils \
services.core \ services.core \
services.devicepolicy \ services.devicepolicy \

View File

@@ -18,6 +18,7 @@ package android.net;
import android.os.Bundle; import android.os.Bundle;
import android.os.Parcel; import android.os.Parcel;
import android.test.suitebuilder.annotation.SmallTest;
import java.util.List; import java.util.List;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.mockito.ArgumentCaptor; import org.mockito.ArgumentCaptor;
@@ -49,6 +50,7 @@ public class ConnectivityMetricsLoggerTest extends TestCase {
mLog = new ConnectivityMetricsLogger(mService); mLog = new ConnectivityMetricsLogger(mService);
} }
@SmallTest
public void testLogEvents() throws Exception { public void testLogEvents() throws Exception {
mLog.logEvent(1, FAKE_COMPONENT, FAKE_EVENT, FAKE_EV); mLog.logEvent(1, FAKE_COMPONENT, FAKE_EVENT, FAKE_EV);
mLog.logEvent(2, FAKE_COMPONENT, FAKE_EVENT, FAKE_EV); mLog.logEvent(2, FAKE_COMPONENT, FAKE_EVENT, FAKE_EV);
@@ -60,6 +62,7 @@ public class ConnectivityMetricsLoggerTest extends TestCase {
assertEventsEqual(expectedEvent(3), gotEvents.get(2)); assertEventsEqual(expectedEvent(3), gotEvents.get(2));
} }
@SmallTest
public void testLogEventTriggerThrottling() throws Exception { public void testLogEventTriggerThrottling() throws Exception {
when(mService.logEvent(any())).thenReturn(1234L); when(mService.logEvent(any())).thenReturn(1234L);
@@ -70,6 +73,7 @@ public class ConnectivityMetricsLoggerTest extends TestCase {
assertEventsEqual(expectedEvent(1), gotEvents.get(0)); assertEventsEqual(expectedEvent(1), gotEvents.get(0));
} }
@SmallTest
public void testLogEventFails() throws Exception { public void testLogEventFails() throws Exception {
when(mService.logEvent(any())).thenReturn(-1L); // Error. when(mService.logEvent(any())).thenReturn(-1L); // Error.
@@ -80,6 +84,7 @@ public class ConnectivityMetricsLoggerTest extends TestCase {
assertEventsEqual(expectedEvent(1), gotEvents.get(0)); assertEventsEqual(expectedEvent(1), gotEvents.get(0));
} }
@SmallTest
public void testLogEventWhenThrottling() throws Exception { public void testLogEventWhenThrottling() throws Exception {
when(mService.logEvent(any())).thenReturn(Long.MAX_VALUE); // Throttled when(mService.logEvent(any())).thenReturn(Long.MAX_VALUE); // Throttled
@@ -92,6 +97,7 @@ public class ConnectivityMetricsLoggerTest extends TestCase {
assertEventsEqual(expectedEvent(1), gotEvents.get(0)); assertEventsEqual(expectedEvent(1), gotEvents.get(0));
} }
@SmallTest
public void testLogEventRecoverFromThrottling() throws Exception { public void testLogEventRecoverFromThrottling() throws Exception {
final long throttleTimeout = System.currentTimeMillis() + 10; final long throttleTimeout = System.currentTimeMillis() + 10;
when(mService.logEvent(any())).thenReturn(throttleTimeout, 0L); when(mService.logEvent(any())).thenReturn(throttleTimeout, 0L);

View File

@@ -33,7 +33,6 @@ import android.system.ErrnoException;
import android.system.Os; import android.system.Os;
import android.test.AndroidTestCase; import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import android.test.suitebuilder.annotation.MediumTest;
import static android.system.OsConstants.*; import static android.system.OsConstants.*;
import com.android.frameworks.tests.net.R; import com.android.frameworks.tests.net.R;
@@ -155,7 +154,7 @@ public class ApfTest extends AndroidTestCase {
* generating bytecode for that program and running it through the * generating bytecode for that program and running it through the
* interpreter to verify it functions correctly. * interpreter to verify it functions correctly.
*/ */
@MediumTest @SmallTest
public void testApfInstructions() throws IllegalInstructionException { public void testApfInstructions() throws IllegalInstructionException {
// Empty program should pass because having the program counter reach the // Empty program should pass because having the program counter reach the
// location immediately after the program indicates the packet should be // location immediately after the program indicates the packet should be
@@ -563,7 +562,7 @@ public class ApfTest extends AndroidTestCase {
* Generate some BPF programs, translate them to APF, then run APF and BPF programs * Generate some BPF programs, translate them to APF, then run APF and BPF programs
* over packet traces and verify both programs filter out the same packets. * over packet traces and verify both programs filter out the same packets.
*/ */
@MediumTest @SmallTest
public void testApfAgainstBpf() throws Exception { public void testApfAgainstBpf() throws Exception {
String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53", String[] tcpdump_filters = new String[]{ "udp", "tcp", "icmp", "icmp6", "udp port 53",
"arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24", "arp", "dst 239.255.255.250", "arp or tcp or udp port 53", "net 192.168.1.0/24",
@@ -725,7 +724,7 @@ public class ApfTest extends AndroidTestCase {
private static final byte[] ANOTHER_IPV4_ADDR = {10, 0, 0, 2}; private static final byte[] ANOTHER_IPV4_ADDR = {10, 0, 0, 2};
private static final byte[] IPV4_ANY_HOST_ADDR = {0, 0, 0, 0}; private static final byte[] IPV4_ANY_HOST_ADDR = {0, 0, 0, 0};
@MediumTest @SmallTest
public void testApfFilterIPv4() throws Exception { public void testApfFilterIPv4() throws Exception {
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19); LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
@@ -780,7 +779,7 @@ public class ApfTest extends AndroidTestCase {
apfFilter.shutdown(); apfFilter.shutdown();
} }
@MediumTest @SmallTest
public void testApfFilterIPv6() throws Exception { public void testApfFilterIPv6() throws Exception {
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog);
@@ -812,7 +811,7 @@ public class ApfTest extends AndroidTestCase {
apfFilter.shutdown(); apfFilter.shutdown();
} }
@MediumTest @SmallTest
public void testApfFilterMulticast() throws Exception { public void testApfFilterMulticast() throws Exception {
final byte[] unicastIpv4Addr = {(byte)192,0,2,63}; final byte[] unicastIpv4Addr = {(byte)192,0,2,63};
final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255}; final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255};
@@ -922,7 +921,7 @@ public class ApfTest extends AndroidTestCase {
assertDrop(program, garpReply()); assertDrop(program, garpReply());
} }
@MediumTest @SmallTest
public void testApfFilterArp() throws Exception { public void testApfFilterArp() throws Exception {
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog); ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog);
@@ -1041,7 +1040,7 @@ public class ApfTest extends AndroidTestCase {
ipManagerCallback.assertNoProgramUpdate(); ipManagerCallback.assertNoProgramUpdate();
} }
@MediumTest @SmallTest
public void testApfFilterRa() throws Exception { public void testApfFilterRa() throws Exception {
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback(); MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
TestApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog); TestApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog);

View File

@@ -473,6 +473,7 @@ public class DhcpPacketTest extends TestCase {
assertEquals(Integer.toHexString(expected), Integer.toHexString(got)); assertEquals(Integer.toHexString(expected), Integer.toHexString(got));
} }
@SmallTest
public void testTruncatedOfferPackets() throws Exception { public void testTruncatedOfferPackets() throws Exception {
final byte[] packet = HexDump.hexStringToByteArray( final byte[] packet = HexDump.hexStringToByteArray(
// IP header. // IP header.
@@ -506,6 +507,7 @@ public class DhcpPacketTest extends TestCase {
} }
} }
@SmallTest
public void testRandomPackets() throws Exception { public void testRandomPackets() throws Exception {
final int maxRandomPacketSize = 512; final int maxRandomPacketSize = 512;
final Random r = new Random(); final Random r = new Random();

View File

@@ -24,6 +24,7 @@ import android.net.netlink.NetlinkConstants;
import android.net.netlink.NetlinkErrorMessage; import android.net.netlink.NetlinkErrorMessage;
import android.net.netlink.NetlinkMessage; import android.net.netlink.NetlinkMessage;
import android.net.netlink.StructNlMsgErr; import android.net.netlink.StructNlMsgErr;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log; import android.util.Log;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
@@ -53,6 +54,7 @@ public class NetlinkErrorMessageTest extends TestCase {
public static final byte[] NLM_ERROR_OK = public static final byte[] NLM_ERROR_OK =
HexEncoding.decode(NLM_ERROR_OK_HEX.toCharArray(), false); HexEncoding.decode(NLM_ERROR_OK_HEX.toCharArray(), false);
@SmallTest
public void testParseNlmErrorOk() { public void testParseNlmErrorOk() {
final ByteBuffer byteBuffer = ByteBuffer.wrap(NLM_ERROR_OK); final ByteBuffer byteBuffer = ByteBuffer.wrap(NLM_ERROR_OK);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.

View File

@@ -20,6 +20,7 @@ import android.net.netlink.NetlinkSocket;
import android.net.netlink.RtNetlinkNeighborMessage; import android.net.netlink.RtNetlinkNeighborMessage;
import android.net.netlink.StructNdMsg; import android.net.netlink.StructNdMsg;
import android.net.netlink.StructNlMsgHdr; import android.net.netlink.StructNlMsgHdr;
import android.test.suitebuilder.annotation.SmallTest;
import android.system.ErrnoException; import android.system.ErrnoException;
import android.system.NetlinkSocketAddress; import android.system.NetlinkSocketAddress;
import android.system.OsConstants; import android.system.OsConstants;
@@ -33,6 +34,7 @@ import junit.framework.TestCase;
public class NetlinkSocketTest extends TestCase { public class NetlinkSocketTest extends TestCase {
private final String TAG = "NetlinkSocketTest"; private final String TAG = "NetlinkSocketTest";
@SmallTest
public void testBasicWorkingGetNeighborsQuery() throws Exception { public void testBasicWorkingGetNeighborsQuery() throws Exception {
NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE); NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);
assertNotNull(s); assertNotNull(s);
@@ -91,6 +93,7 @@ public class NetlinkSocketTest extends TestCase {
s.close(); s.close();
} }
@SmallTest
public void testRepeatedCloseCallsAreQuiet() throws Exception { public void testRepeatedCloseCallsAreQuiet() throws Exception {
// Create a working NetlinkSocket. // Create a working NetlinkSocket.
NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE); NetlinkSocket s = new NetlinkSocket(OsConstants.NETLINK_ROUTE);

View File

@@ -21,12 +21,13 @@ import android.net.netlink.NetlinkMessage;
import android.net.netlink.RtNetlinkNeighborMessage; import android.net.netlink.RtNetlinkNeighborMessage;
import android.net.netlink.StructNdMsg; import android.net.netlink.StructNdMsg;
import android.net.netlink.StructNlMsgHdr; import android.net.netlink.StructNlMsgHdr;
import android.test.suitebuilder.annotation.SmallTest;
import android.system.OsConstants; import android.system.OsConstants;
import android.util.Log; import android.util.Log;
import libcore.util.HexEncoding; import libcore.util.HexEncoding;
import java.net.InetAddress;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
@@ -135,6 +136,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase {
public static final byte[] RTM_GETNEIGH_RESPONSE = public static final byte[] RTM_GETNEIGH_RESPONSE =
HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false); HexEncoding.decode(RTM_GETNEIGH_RESPONSE_HEX.replaceAll(" ", "").toCharArray(), false);
@SmallTest
public void testParseRtmDelNeigh() { public void testParseRtmDelNeigh() {
final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH); final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_DELNEIGH);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
@@ -161,6 +163,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase {
assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination); assertEquals(InetAddress.parseNumericAddress("192.168.159.254"), destination);
} }
@SmallTest
public void testParseRtmNewNeigh() { public void testParseRtmNewNeigh() {
final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH); final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_NEWNEIGH);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
@@ -187,6 +190,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase {
assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination); assertEquals(InetAddress.parseNumericAddress("fe80::86c9:b2ff:fe6a:ed4b"), destination);
} }
@SmallTest
public void testParseRtmGetNeighResponse() { public void testParseRtmGetNeighResponse() {
final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE); final ByteBuffer byteBuffer = ByteBuffer.wrap(RTM_GETNEIGH_RESPONSE);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing. byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.
@@ -211,6 +215,7 @@ public class RtNetlinkNeighborMessageTest extends TestCase {
assertEquals(14, messageCount); assertEquals(14, messageCount);
} }
@SmallTest
public void testCreateRtmNewNeighMessage() { public void testCreateRtmNewNeighMessage() {
final int seqNo = 2635; final int seqNo = 2635;
final int ifIndex = 14; final int ifIndex = 14;

View File

@@ -70,7 +70,6 @@ import android.provider.Settings;
import android.test.AndroidTestCase; import android.test.AndroidTestCase;
import android.test.FlakyTest; import android.test.FlakyTest;
import android.test.mock.MockContentResolver; import android.test.mock.MockContentResolver;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log; import android.util.Log;
import android.util.LogPrinter; import android.util.LogPrinter;
@@ -196,6 +195,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
} }
// Tests that IdleableHandlerThread works as expected. // Tests that IdleableHandlerThread works as expected.
@SmallTest
public void testIdleableHandlerThread() { public void testIdleableHandlerThread() {
final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng. final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
@@ -220,6 +220,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
} }
} }
@SmallTest
@FlakyTest(tolerance = 3) @FlakyTest(tolerance = 3)
public void testNotWaitingForIdleCausesRaceConditions() { public void testNotWaitingForIdleCausesRaceConditions() {
// Bring up a network that we can use to send messages to ConnectivityService. // Bring up a network that we can use to send messages to ConnectivityService.
@@ -840,7 +841,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
return cv; return cv;
} }
@LargeTest @SmallTest
public void testLingering() throws Exception { public void testLingering() throws Exception {
verifyNoNetwork(); verifyNoNetwork();
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -880,7 +881,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
verifyNoNetwork(); verifyNoNetwork();
} }
@LargeTest @SmallTest
public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception { public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception {
// Test bringing up unvalidated WiFi // Test bringing up unvalidated WiFi
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -915,7 +916,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
verifyNoNetwork(); verifyNoNetwork();
} }
@LargeTest @SmallTest
public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception { public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception {
// Test bringing up unvalidated cellular. // Test bringing up unvalidated cellular.
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -941,7 +942,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
verifyNoNetwork(); verifyNoNetwork();
} }
@LargeTest @SmallTest
public void testUnlingeringDoesNotValidate() throws Exception { public void testUnlingeringDoesNotValidate() throws Exception {
// Test bringing up unvalidated WiFi. // Test bringing up unvalidated WiFi.
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -969,7 +970,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
NET_CAPABILITY_VALIDATED)); NET_CAPABILITY_VALIDATED));
} }
@LargeTest @SmallTest
public void testCellularOutscoresWeakWifi() throws Exception { public void testCellularOutscoresWeakWifi() throws Exception {
// Test bringing up validated cellular. // Test bringing up validated cellular.
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -995,7 +996,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
verifyActiveNetwork(TRANSPORT_WIFI); verifyActiveNetwork(TRANSPORT_WIFI);
} }
@LargeTest @SmallTest
public void testReapingNetwork() throws Exception { public void testReapingNetwork() throws Exception {
// Test bringing up WiFi without NET_CAPABILITY_INTERNET. // Test bringing up WiFi without NET_CAPABILITY_INTERNET.
// Expect it to be torn down immediately because it satisfies no requests. // Expect it to be torn down immediately because it satisfies no requests.
@@ -1028,7 +1029,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
waitFor(cv); waitFor(cv);
} }
@LargeTest @SmallTest
public void testCellularFallback() throws Exception { public void testCellularFallback() throws Exception {
// Test bringing up validated cellular. // Test bringing up validated cellular.
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1066,7 +1067,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
verifyActiveNetwork(TRANSPORT_WIFI); verifyActiveNetwork(TRANSPORT_WIFI);
} }
@LargeTest @SmallTest
public void testWiFiFallback() throws Exception { public void testWiFiFallback() throws Exception {
// Test bringing up unvalidated WiFi. // Test bringing up unvalidated WiFi.
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
@@ -1208,7 +1209,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
} }
} }
@LargeTest @SmallTest
public void testStateChangeNetworkCallbacks() throws Exception { public void testStateChangeNetworkCallbacks() throws Exception {
final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback(); final TestNetworkCallback genericNetworkCallback = new TestNetworkCallback();
final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback(); final TestNetworkCallback wifiNetworkCallback = new TestNetworkCallback();
@@ -1591,7 +1592,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
handlerThread.quit(); handlerThread.quit();
} }
@LargeTest @SmallTest
public void testNetworkFactoryRequests() throws Exception { public void testNetworkFactoryRequests() throws Exception {
tryNetworkFactoryRequests(NET_CAPABILITY_MMS); tryNetworkFactoryRequests(NET_CAPABILITY_MMS);
tryNetworkFactoryRequests(NET_CAPABILITY_SUPL); tryNetworkFactoryRequests(NET_CAPABILITY_SUPL);
@@ -1611,7 +1612,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
// Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed. // Skipping VALIDATED and CAPTIVE_PORTAL as they're disallowed.
} }
@LargeTest @SmallTest
public void testNoMutableNetworkRequests() throws Exception { public void testNoMutableNetworkRequests() throws Exception {
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0); PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, new Intent("a"), 0);
NetworkRequest.Builder builder = new NetworkRequest.Builder(); NetworkRequest.Builder builder = new NetworkRequest.Builder();
@@ -1636,7 +1637,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
} catch (IllegalArgumentException expected) {} } catch (IllegalArgumentException expected) {}
} }
@LargeTest @SmallTest
public void testMMSonWiFi() throws Exception { public void testMMSonWiFi() throws Exception {
// Test bringing up cellular without MMS NetworkRequest gets reaped // Test bringing up cellular without MMS NetworkRequest gets reaped
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1671,7 +1672,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
verifyActiveNetwork(TRANSPORT_WIFI); verifyActiveNetwork(TRANSPORT_WIFI);
} }
@LargeTest @SmallTest
public void testMMSonCell() throws Exception { public void testMMSonCell() throws Exception {
// Test bringing up cellular without MMS // Test bringing up cellular without MMS
mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR);
@@ -1697,7 +1698,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
verifyActiveNetwork(TRANSPORT_CELLULAR); verifyActiveNetwork(TRANSPORT_CELLULAR);
} }
@LargeTest @SmallTest
public void testCaptivePortal() { public void testCaptivePortal() {
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
@@ -1746,7 +1747,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent); validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
} }
@LargeTest @SmallTest
public void testAvoidOrIgnoreCaptivePortals() { public void testAvoidOrIgnoreCaptivePortals() {
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback(); final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
final NetworkRequest captivePortalRequest = new NetworkRequest.Builder() final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
@@ -1817,7 +1818,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
execptionCalled); execptionCalled);
} }
@LargeTest @SmallTest
public void testRegisterDefaultNetworkCallback() throws Exception { public void testRegisterDefaultNetworkCallback() throws Exception {
final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback(); final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
mCm.registerDefaultNetworkCallback(defaultNetworkCallback); mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
@@ -1878,7 +1879,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
} }
} }
@LargeTest @SmallTest
public void testRequestCallbackUpdates() throws Exception { public void testRequestCallbackUpdates() throws Exception {
// File a network request for mobile. // File a network request for mobile.
final TestNetworkCallback cellNetworkCallback = new TestRequestUpdateCallback(); final TestNetworkCallback cellNetworkCallback = new TestRequestUpdateCallback();
@@ -2519,6 +2520,7 @@ public class ConnectivityServiceTest extends AndroidTestCase {
return mWiFiNetworkAgent.getNetwork(); return mWiFiNetworkAgent.getNetwork();
} }
@SmallTest
public void testPacketKeepalives() throws Exception { public void testPacketKeepalives() throws Exception {
InetAddress myIPv4 = InetAddress.getByName("192.0.2.129"); InetAddress myIPv4 = InetAddress.getByName("192.0.2.129");
InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35"); InetAddress notMyIPv4 = InetAddress.getByName("192.0.2.35");

View File

@@ -24,6 +24,7 @@ import android.net.Network;
import android.net.NetworkCapabilities; import android.net.NetworkCapabilities;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.net.NetworkMisc; import android.net.NetworkMisc;
import android.test.suitebuilder.annotation.SmallTest;
import android.text.format.DateUtils; import android.text.format.DateUtils;
import com.android.internal.R; import com.android.internal.R;
import com.android.server.ConnectivityService; import com.android.server.ConnectivityService;
@@ -70,6 +71,7 @@ public class LingerMonitorTest extends TestCase {
mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT); mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, HIGH_RATE_LIMIT);
} }
@SmallTest
public void testTransitions() { public void testTransitions() {
setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationSwitch(transition(WIFI, CELLULAR));
NetworkAgentInfo nai1 = wifiNai(100); NetworkAgentInfo nai1 = wifiNai(100);
@@ -79,6 +81,7 @@ public class LingerMonitorTest extends TestCase {
assertFalse(mMonitor.isNotificationEnabled(nai2, nai1)); assertFalse(mMonitor.isNotificationEnabled(nai2, nai1));
} }
@SmallTest
public void testNotificationOnLinger() { public void testNotificationOnLinger() {
setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationSwitch(transition(WIFI, CELLULAR));
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -89,6 +92,7 @@ public class LingerMonitorTest extends TestCase {
verifyNotification(from, to); verifyNotification(from, to);
} }
@SmallTest
public void testToastOnLinger() { public void testToastOnLinger() {
setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationSwitch(transition(WIFI, CELLULAR));
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
@@ -99,6 +103,7 @@ public class LingerMonitorTest extends TestCase {
verifyToast(from, to); verifyToast(from, to);
} }
@SmallTest
public void testNotificationClearedAfterDisconnect() { public void testNotificationClearedAfterDisconnect() {
setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationSwitch(transition(WIFI, CELLULAR));
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -112,6 +117,7 @@ public class LingerMonitorTest extends TestCase {
verify(mNotifier, times(1)).clearNotification(100); verify(mNotifier, times(1)).clearNotification(100);
} }
@SmallTest
public void testNotificationClearedAfterSwitchingBack() { public void testNotificationClearedAfterSwitchingBack() {
setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationSwitch(transition(WIFI, CELLULAR));
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -125,6 +131,7 @@ public class LingerMonitorTest extends TestCase {
verify(mNotifier, times(1)).clearNotification(100); verify(mNotifier, times(1)).clearNotification(100);
} }
@SmallTest
public void testUniqueToast() { public void testUniqueToast() {
setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationSwitch(transition(WIFI, CELLULAR));
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
@@ -142,6 +149,7 @@ public class LingerMonitorTest extends TestCase {
verifyNoNotifications(); verifyNoNotifications();
} }
@SmallTest
public void testMultipleNotifications() { public void testMultipleNotifications() {
setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationSwitch(transition(WIFI, CELLULAR));
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -160,6 +168,7 @@ public class LingerMonitorTest extends TestCase {
verifyNotification(wifi2, cell); verifyNotification(wifi2, cell);
} }
@SmallTest
public void testRateLimiting() throws InterruptedException { public void testRateLimiting() throws InterruptedException {
mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, LOW_RATE_LIMIT); mMonitor = new TestableLingerMonitor(mCtx, mNotifier, HIGH_DAILY_LIMIT, LOW_RATE_LIMIT);
@@ -185,6 +194,7 @@ public class LingerMonitorTest extends TestCase {
verifyNoNotifications(); verifyNoNotifications();
} }
@SmallTest
public void testDailyLimiting() throws InterruptedException { public void testDailyLimiting() throws InterruptedException {
mMonitor = new TestableLingerMonitor(mCtx, mNotifier, LOW_DAILY_LIMIT, HIGH_RATE_LIMIT); mMonitor = new TestableLingerMonitor(mCtx, mNotifier, LOW_DAILY_LIMIT, HIGH_RATE_LIMIT);
@@ -211,6 +221,7 @@ public class LingerMonitorTest extends TestCase {
verifyNoNotifications(); verifyNoNotifications();
} }
@SmallTest
public void testUniqueNotification() { public void testUniqueNotification() {
setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationSwitch(transition(WIFI, CELLULAR));
setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION); setNotificationType(LingerMonitor.NOTIFY_TYPE_NOTIFICATION);
@@ -227,6 +238,7 @@ public class LingerMonitorTest extends TestCase {
verifyNotification(from, to); verifyNotification(from, to);
} }
@SmallTest
public void testIgnoreNeverValidatedNetworks() { public void testIgnoreNeverValidatedNetworks() {
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -238,6 +250,7 @@ public class LingerMonitorTest extends TestCase {
verifyNoNotifications(); verifyNoNotifications();
} }
@SmallTest
public void testIgnoreCurrentlyValidatedNetworks() { public void testIgnoreCurrentlyValidatedNetworks() {
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -249,6 +262,7 @@ public class LingerMonitorTest extends TestCase {
verifyNoNotifications(); verifyNoNotifications();
} }
@SmallTest
public void testNoNotificationType() { public void testNoNotificationType() {
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
setNotificationSwitch(); setNotificationSwitch();
@@ -259,6 +273,7 @@ public class LingerMonitorTest extends TestCase {
verifyNoNotifications(); verifyNoNotifications();
} }
@SmallTest
public void testNoTransitionToNotify() { public void testNoTransitionToNotify() {
setNotificationType(LingerMonitor.NOTIFY_TYPE_NONE); setNotificationType(LingerMonitor.NOTIFY_TYPE_NONE);
setNotificationSwitch(transition(WIFI, CELLULAR)); setNotificationSwitch(transition(WIFI, CELLULAR));
@@ -269,6 +284,7 @@ public class LingerMonitorTest extends TestCase {
verifyNoNotifications(); verifyNoNotifications();
} }
@SmallTest
public void testDifferentTransitionToNotify() { public void testDifferentTransitionToNotify() {
setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST); setNotificationType(LingerMonitor.NOTIFY_TYPE_TOAST);
setNotificationSwitch(transition(CELLULAR, WIFI)); setNotificationSwitch(transition(CELLULAR, WIFI));

View File

@@ -20,6 +20,7 @@ import android.content.Context;
import android.net.ConnectivityMetricsEvent; import android.net.ConnectivityMetricsEvent;
import android.os.Bundle; import android.os.Bundle;
import android.os.RemoteException; import android.os.RemoteException;
import android.test.suitebuilder.annotation.SmallTest;
import static android.net.ConnectivityMetricsEvent.Reference; import static android.net.ConnectivityMetricsEvent.Reference;
import junit.framework.TestCase; import junit.framework.TestCase;
@@ -67,12 +68,14 @@ public class MetricsLoggerServiceTest extends TestCase {
mService.onStart(); mService.onStart();
} }
@SmallTest
public void testGetNoEvents() throws Exception { public void testGetNoEvents() throws Exception {
Reference r = new Reference(0); Reference r = new Reference(0);
assertArrayEquals(NO_EVENTS, mService.mBinder.getEvents(r)); assertArrayEquals(NO_EVENTS, mService.mBinder.getEvents(r));
assertEquals(0, r.getValue()); assertEquals(0, r.getValue());
} }
@SmallTest
public void testLogAndGetEvents() throws Exception { public void testLogAndGetEvents() throws Exception {
mService.mBinder.logEvents(EVENTS); mService.mBinder.logEvents(EVENTS);
@@ -85,6 +88,7 @@ public class MetricsLoggerServiceTest extends TestCase {
assertEquals(N_EVENTS, r.getValue()); assertEquals(N_EVENTS, r.getValue());
} }
@SmallTest
public void testLogOneByOne() throws Exception { public void testLogOneByOne() throws Exception {
for (ConnectivityMetricsEvent ev : EVENTS) { for (ConnectivityMetricsEvent ev : EVENTS) {
mService.mBinder.logEvent(ev); mService.mBinder.logEvent(ev);
@@ -99,6 +103,7 @@ public class MetricsLoggerServiceTest extends TestCase {
assertEquals(N_EVENTS, r.getValue()); assertEquals(N_EVENTS, r.getValue());
} }
@SmallTest
public void testInterleavedLogAndGet() throws Exception { public void testInterleavedLogAndGet() throws Exception {
mService.mBinder.logEvents(Arrays.copyOfRange(EVENTS, 0, 3)); mService.mBinder.logEvents(Arrays.copyOfRange(EVENTS, 0, 3));
@@ -117,6 +122,7 @@ public class MetricsLoggerServiceTest extends TestCase {
assertEquals(N_EVENTS, r.getValue()); assertEquals(N_EVENTS, r.getValue());
} }
@SmallTest
public void testMultipleGetAll() throws Exception { public void testMultipleGetAll() throws Exception {
mService.mBinder.logEvents(Arrays.copyOf(EVENTS, 3)); mService.mBinder.logEvents(Arrays.copyOf(EVENTS, 3));
@@ -131,6 +137,7 @@ public class MetricsLoggerServiceTest extends TestCase {
assertEquals(N_EVENTS, r2.getValue()); assertEquals(N_EVENTS, r2.getValue());
} }
@SmallTest
public void testLogAndDumpConcurrently() throws Exception { public void testLogAndDumpConcurrently() throws Exception {
for (int i = 0; i < 50; i++) { for (int i = 0; i < 50; i++) {
mContext = null; mContext = null;

View File

@@ -22,6 +22,8 @@ import android.net.Network;
import android.net.metrics.DnsEvent; import android.net.metrics.DnsEvent;
import android.net.metrics.INetdEventListener; import android.net.metrics.INetdEventListener;
import android.net.metrics.IpConnectivityLog; import android.net.metrics.IpConnectivityLog;
import android.os.RemoteException;
import android.test.suitebuilder.annotation.SmallTest;
import junit.framework.TestCase; import junit.framework.TestCase;
import org.junit.Before; import org.junit.Before;
@@ -82,6 +84,7 @@ public class NetdEventListenerServiceTest extends TestCase {
verify(mCm, times(1)).registerNetworkCallback(any(), mCallbackCaptor.capture()); verify(mCm, times(1)).registerNetworkCallback(any(), mCallbackCaptor.capture());
} }
@SmallTest
public void testOneBatch() throws Exception { public void testOneBatch() throws Exception {
log(105, LATENCIES); log(105, LATENCIES);
log(106, Arrays.copyOf(LATENCIES, BATCH_SIZE - 1)); // one lookup short of a batch event log(106, Arrays.copyOf(LATENCIES, BATCH_SIZE - 1)); // one lookup short of a batch event
@@ -96,6 +99,7 @@ public class NetdEventListenerServiceTest extends TestCase {
new DnsEvent(106, EVENT_TYPES, RETURN_CODES, LATENCIES)); new DnsEvent(106, EVENT_TYPES, RETURN_CODES, LATENCIES));
} }
@SmallTest
public void testSeveralBatches() throws Exception { public void testSeveralBatches() throws Exception {
log(105, LATENCIES); log(105, LATENCIES);
log(106, LATENCIES); log(106, LATENCIES);
@@ -109,6 +113,7 @@ public class NetdEventListenerServiceTest extends TestCase {
new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES)); new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES));
} }
@SmallTest
public void testBatchAndNetworkLost() throws Exception { public void testBatchAndNetworkLost() throws Exception {
byte[] eventTypes = Arrays.copyOf(EVENT_TYPES, 20); byte[] eventTypes = Arrays.copyOf(EVENT_TYPES, 20);
byte[] returnCodes = Arrays.copyOf(RETURN_CODES, 20); byte[] returnCodes = Arrays.copyOf(RETURN_CODES, 20);
@@ -125,6 +130,7 @@ public class NetdEventListenerServiceTest extends TestCase {
new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES)); new DnsEvent(105, EVENT_TYPES, RETURN_CODES, LATENCIES));
} }
@SmallTest
public void testConcurrentBatchesAndDumps() throws Exception { public void testConcurrentBatchesAndDumps() throws Exception {
final long stop = System.currentTimeMillis() + 100; final long stop = System.currentTimeMillis() + 100;
final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null")); final PrintWriter pw = new PrintWriter(new FileOutputStream("/dev/null"));
@@ -146,6 +152,7 @@ public class NetdEventListenerServiceTest extends TestCase {
new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES)); new DnsEvent(107, EVENT_TYPES, RETURN_CODES, LATENCIES));
} }
@SmallTest
public void testConcurrentBatchesAndNetworkLoss() throws Exception { public void testConcurrentBatchesAndNetworkLoss() throws Exception {
logAsync(105, LATENCIES); logAsync(105, LATENCIES);
Thread.sleep(10L); Thread.sleep(10L);
@@ -157,9 +164,13 @@ public class NetdEventListenerServiceTest extends TestCase {
} }
void log(int netId, int[] latencies) { void log(int netId, int[] latencies) {
for (int l : latencies) { try {
mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null, 0, for (int l : latencies) {
0); mNetdEventListenerService.onDnsEvent(netId, EVENT_TYPE, RETURN_CODE, l, null, null,
0, 0);
}
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
} }
} }

View File

@@ -25,9 +25,11 @@ import static org.mockito.Mockito.*;
import android.annotation.UserIdInt; import android.annotation.UserIdInt;
import android.app.AppOpsManager; import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.UserInfo; import android.content.pm.UserInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.UidRange; import android.net.UidRange;
import android.os.INetworkManagementService; import android.os.INetworkManagementService;
import android.os.Looper; import android.os.Looper;
@@ -43,6 +45,8 @@ import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.mockito.ArgumentCaptor;
import org.mockito.InOrder;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.MockitoAnnotations; import org.mockito.MockitoAnnotations;
@@ -88,14 +92,18 @@ public class VpnTest extends AndroidTestCase {
@Mock private PackageManager mPackageManager; @Mock private PackageManager mPackageManager;
@Mock private INetworkManagementService mNetService; @Mock private INetworkManagementService mNetService;
@Mock private AppOpsManager mAppOps; @Mock private AppOpsManager mAppOps;
@Mock private NotificationManager mNotificationManager;
@Override @Override
public void setUp() throws Exception { public void setUp() throws Exception {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mContext.getPackageManager()).thenReturn(mPackageManager);
setMockedPackages(mPackages); setMockedPackages(mPackages);
when(mContext.getPackageName()).thenReturn(Vpn.class.getPackage().getName());
when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager); when(mContext.getSystemService(eq(Context.USER_SERVICE))).thenReturn(mUserManager);
when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps); when(mContext.getSystemService(eq(Context.APP_OPS_SERVICE))).thenReturn(mAppOps);
when(mContext.getSystemService(eq(Context.NOTIFICATION_SERVICE)))
.thenReturn(mNotificationManager);
doNothing().when(mNetService).registerObserver(any()); doNothing().when(mNetService).registerObserver(any());
} }
@@ -103,7 +111,7 @@ public class VpnTest extends AndroidTestCase {
public void testRestrictedProfilesAreAddedToVpn() { public void testRestrictedProfilesAreAddedToVpn() {
setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB); setMockedUsers(primaryUser, secondaryUser, restrictedProfileA, restrictedProfileB);
final Vpn vpn = new MockVpn(primaryUser.id); final Vpn vpn = spyVpn(primaryUser.id);
final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
null, null); null, null);
@@ -117,7 +125,7 @@ public class VpnTest extends AndroidTestCase {
public void testManagedProfilesAreNotAddedToVpn() { public void testManagedProfilesAreNotAddedToVpn() {
setMockedUsers(primaryUser, managedProfileA); setMockedUsers(primaryUser, managedProfileA);
final Vpn vpn = new MockVpn(primaryUser.id); final Vpn vpn = spyVpn(primaryUser.id);
final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id, final Set<UidRange> ranges = vpn.createUserAndRestrictedProfilesRanges(primaryUser.id,
null, null); null, null);
@@ -130,7 +138,7 @@ public class VpnTest extends AndroidTestCase {
public void testAddUserToVpnOnlyAddsOneUser() { public void testAddUserToVpnOnlyAddsOneUser() {
setMockedUsers(primaryUser, restrictedProfileA, managedProfileA); setMockedUsers(primaryUser, restrictedProfileA, managedProfileA);
final Vpn vpn = new MockVpn(primaryUser.id); final Vpn vpn = spyVpn(primaryUser.id);
final Set<UidRange> ranges = new ArraySet<>(); final Set<UidRange> ranges = new ArraySet<>();
vpn.addUserToRanges(ranges, primaryUser.id, null, null); vpn.addUserToRanges(ranges, primaryUser.id, null, null);
@@ -141,7 +149,7 @@ public class VpnTest extends AndroidTestCase {
@SmallTest @SmallTest
public void testUidWhiteAndBlacklist() throws Exception { public void testUidWhiteAndBlacklist() throws Exception {
final Vpn vpn = new MockVpn(primaryUser.id); final Vpn vpn = spyVpn(primaryUser.id);
final UidRange user = UidRange.createForUser(primaryUser.id); final UidRange user = UidRange.createForUser(primaryUser.id);
final String[] packages = {PKGS[0], PKGS[1], PKGS[2]}; final String[] packages = {PKGS[0], PKGS[1], PKGS[2]};
@@ -166,15 +174,15 @@ public class VpnTest extends AndroidTestCase {
@SmallTest @SmallTest
public void testLockdownChangingPackage() throws Exception { public void testLockdownChangingPackage() throws Exception {
final MockVpn vpn = new MockVpn(primaryUser.id); final Vpn vpn = spyVpn(primaryUser.id);
final UidRange user = UidRange.createForUser(primaryUser.id); final UidRange user = UidRange.createForUser(primaryUser.id);
// Default state. // Default state.
vpn.assertUnblocked(user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]); assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
// Set always-on without lockdown. // Set always-on without lockdown.
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false)); assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false));
vpn.assertUnblocked(user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]); assertUnblocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
// Set always-on with lockdown. // Set always-on with lockdown.
assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true)); assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true));
@@ -182,8 +190,8 @@ public class VpnTest extends AndroidTestCase {
new UidRange(user.start, user.start + PKG_UIDS[1] - 1), new UidRange(user.start, user.start + PKG_UIDS[1] - 1),
new UidRange(user.start + PKG_UIDS[1] + 1, user.stop) new UidRange(user.start + PKG_UIDS[1] + 1, user.stop)
})); }));
vpn.assertBlocked(user.start + PKG_UIDS[0], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]); assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[2], user.start + PKG_UIDS[3]);
vpn.assertUnblocked(user.start + PKG_UIDS[1]); assertUnblocked(vpn, user.start + PKG_UIDS[1]);
// Switch to another app. // Switch to another app.
assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true)); assertTrue(vpn.setAlwaysOnPackage(PKGS[3], true));
@@ -195,13 +203,13 @@ public class VpnTest extends AndroidTestCase {
new UidRange(user.start, user.start + PKG_UIDS[3] - 1), new UidRange(user.start, user.start + PKG_UIDS[3] - 1),
new UidRange(user.start + PKG_UIDS[3] + 1, user.stop) new UidRange(user.start + PKG_UIDS[3] + 1, user.stop)
})); }));
vpn.assertBlocked(user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]); assertBlocked(vpn, user.start + PKG_UIDS[0], user.start + PKG_UIDS[1], user.start + PKG_UIDS[2]);
vpn.assertUnblocked(user.start + PKG_UIDS[3]); assertUnblocked(vpn, user.start + PKG_UIDS[3]);
} }
@SmallTest @SmallTest
public void testLockdownAddingAProfile() throws Exception { public void testLockdownAddingAProfile() throws Exception {
final MockVpn vpn = new MockVpn(primaryUser.id); final Vpn vpn = spyVpn(primaryUser.id);
setMockedUsers(primaryUser); setMockedUsers(primaryUser);
// Make a copy of the restricted profile, as we're going to mark it deleted halfway through. // Make a copy of the restricted profile, as we're going to mark it deleted halfway through.
@@ -220,7 +228,7 @@ public class VpnTest extends AndroidTestCase {
})); }));
// Verify restricted user isn't affected at first. // Verify restricted user isn't affected at first.
vpn.assertUnblocked(profile.start + PKG_UIDS[0]); assertUnblocked(vpn, profile.start + PKG_UIDS[0]);
// Add the restricted user. // Add the restricted user.
setMockedUsers(primaryUser, tempProfile); setMockedUsers(primaryUser, tempProfile);
@@ -239,24 +247,53 @@ public class VpnTest extends AndroidTestCase {
})); }));
} }
@SmallTest
public void testNotificationShownForAlwaysOnApp() {
final Vpn vpn = spyVpn(primaryUser.id);
final InOrder order = inOrder(vpn);
setMockedUsers(primaryUser);
// Don't show a notification for regular disconnected states.
vpn.updateState(DetailedState.DISCONNECTED, TAG);
order.verify(vpn).updateAlwaysOnNotificationInternal(false);
// Start showing a notification for disconnected once always-on.
vpn.setAlwaysOnPackage(PKGS[0], false);
order.verify(vpn).updateAlwaysOnNotificationInternal(true);
// Stop showing the notification once connected.
vpn.updateState(DetailedState.CONNECTED, TAG);
order.verify(vpn).updateAlwaysOnNotificationInternal(false);
// Show the notification if we disconnect again.
vpn.updateState(DetailedState.DISCONNECTED, TAG);
order.verify(vpn).updateAlwaysOnNotificationInternal(true);
// Notification should be cleared after unsetting always-on package.
vpn.setAlwaysOnPackage(null, false);
order.verify(vpn).updateAlwaysOnNotificationInternal(false);
}
/** /**
* A subclass of {@link Vpn} with some of the fields pre-mocked. * Mock some methods of vpn object.
*/ */
private class MockVpn extends Vpn { private Vpn spyVpn(@UserIdInt int userId) {
public MockVpn(@UserIdInt int userId) { final Vpn vpn = spy(new Vpn(Looper.myLooper(), mContext, mNetService, userId));
super(Looper.myLooper(), mContext, mNetService, userId);
}
public void assertBlocked(int... uids) { // Block calls to the NotificationManager or PendingIntent#getActivity.
for (int uid : uids) { doNothing().when(vpn).updateAlwaysOnNotificationInternal(anyBoolean());
assertTrue("Uid " + uid + " should be blocked", isBlockingUid(uid)); return vpn;
} }
}
public void assertUnblocked(int... uids) { private static void assertBlocked(Vpn vpn, int... uids) {
for (int uid : uids) { for (int uid : uids) {
assertFalse("Uid " + uid + " should not be blocked", isBlockingUid(uid)); assertTrue("Uid " + uid + " should be blocked", vpn.isBlockingUid(uid));
} }
}
private static void assertUnblocked(Vpn vpn, int... uids) {
for (int uid : uids) {
assertFalse("Uid " + uid + " should not be blocked", vpn.isBlockingUid(uid));
} }
} }