DO NOT MERGE: ApfTest: tag tests with @SmallTest or @MediumTest
am: 5d2654124e -s ours
Change-Id: I8cfbe35c719dc2f135ec695f346c555fb45dfa58
diff --git a/cmds/uiautomator/library/Android.mk b/cmds/uiautomator/library/Android.mk
index d65b0833..af2e25a 100644
--- a/cmds/uiautomator/library/Android.mk
+++ b/cmds/uiautomator/library/Android.mk
@@ -18,7 +18,7 @@
uiautomator.core_src_files := $(call all-java-files-under, core-src) \
$(call all-java-files-under, testrunner-src)
-uiautomator.core_java_libraries := android.test.runner core-junit
+uiautomator.core_java_libraries := android.test.runner junit
uiautomator_internal_api_file := $(TARGET_OUT_COMMON_INTERMEDIATES)/PACKAGING/uiautomator_api.txt
uiautomator_internal_removed_api_file := \
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 43c8c81..0afb546 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2592,8 +2592,7 @@
/**
* Called if no network is found in the given timeout time. If no timeout is given,
- * this will not be called. The associated {@link NetworkRequest} will have already
- * been removed and released, as if {@link #unregisterNetworkCallback} had been called.
+ * this will not be called.
* @hide
*/
public void onUnavailable() {}
@@ -2666,26 +2665,6 @@
/** @hide */
public static final int CALLBACK_RESUMED = BASE + 12;
- /** @hide */
- public static String getCallbackName(int whichCallback) {
- switch (whichCallback) {
- case CALLBACK_PRECHECK: return "CALLBACK_PRECHECK";
- case CALLBACK_AVAILABLE: return "CALLBACK_AVAILABLE";
- case CALLBACK_LOSING: return "CALLBACK_LOSING";
- case CALLBACK_LOST: return "CALLBACK_LOST";
- case CALLBACK_UNAVAIL: return "CALLBACK_UNAVAIL";
- case CALLBACK_CAP_CHANGED: return "CALLBACK_CAP_CHANGED";
- case CALLBACK_IP_CHANGED: return "CALLBACK_IP_CHANGED";
- case CALLBACK_RELEASED: return "CALLBACK_RELEASED";
- case CALLBACK_EXIT: return "CALLBACK_EXIT";
- case EXPIRE_LEGACY_REQUEST: return "EXPIRE_LEGACY_REQUEST";
- case CALLBACK_SUSPENDED: return "CALLBACK_SUSPENDED";
- case CALLBACK_RESUMED: return "CALLBACK_RESUMED";
- default:
- return Integer.toString(whichCallback);
- }
- }
-
private class CallbackHandler extends Handler {
private final HashMap<NetworkRequest, NetworkCallback>mCallbackMap;
private final AtomicInteger mRefCount;
@@ -2852,7 +2831,7 @@
private final static int REQUEST = 2;
private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
- NetworkCallback networkCallback, int timeoutMs, int action,
+ NetworkCallback networkCallback, int timeoutSec, int action,
int legacyType) {
if (networkCallback == null) {
throw new IllegalArgumentException("null NetworkCallback");
@@ -2868,7 +2847,7 @@
new Messenger(sCallbackHandler), new Binder());
} else {
networkCallback.networkRequest = mService.requestNetwork(need,
- new Messenger(sCallbackHandler), timeoutMs, new Binder(), legacyType);
+ new Messenger(sCallbackHandler), timeoutSec, new Binder(), legacyType);
}
if (networkCallback.networkRequest != null) {
sNetworkCallback.put(networkCallback.networkRequest, networkCallback);
diff --git a/core/java/android/net/INetworkScoreService.aidl b/core/java/android/net/INetworkScoreService.aidl
index 59cbf6e..542a0a7 100644
--- a/core/java/android/net/INetworkScoreService.aidl
+++ b/core/java/android/net/INetworkScoreService.aidl
@@ -56,17 +56,26 @@
void disableScoring();
/**
- * Register a network subsystem for scoring.
+ * Register a cache to receive scoring updates.
*
* @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
* @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
* @throws SecurityException if the caller is not the system.
- * @throws IllegalArgumentException if a score cache is already registed for this type.
* @hide
*/
void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache);
/**
+ * Unregister a cache to receive scoring updates.
+ *
+ * @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
+ * @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
+ * @throws SecurityException if the caller is not the system.
+ * @hide
+ */
+ void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache);
+
+ /**
* Request a recommendation for the best network to connect to
* taking into account the inputs from the {@link RecommendationRequest}.
*
diff --git a/core/java/android/net/NetworkScoreManager.java b/core/java/android/net/NetworkScoreManager.java
index c301fe3..af21cef 100644
--- a/core/java/android/net/NetworkScoreManager.java
+++ b/core/java/android/net/NetworkScoreManager.java
@@ -279,6 +279,24 @@
}
/**
+ * Unregister a network score cache.
+ *
+ * @param networkType the type of network this cache can handle. See {@link NetworkKey#type}.
+ * @param scoreCache implementation of {@link INetworkScoreCache} to store the scores.
+ * @throws SecurityException if the caller does not hold the
+ * {@link android.Manifest.permission#BROADCAST_NETWORK_PRIVILEGED} permission.
+ * @throws IllegalArgumentException if a score cache is already registered for this type.
+ * @hide
+ */
+ public void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
+ try {
+ mService.unregisterNetworkScoreCache(networkType, scoreCache);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Request a recommendation for which network to connect to.
*
* @param request a {@link RecommendationRequest} instance containing additional
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1a8ba74..1350bfa 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7646,6 +7646,8 @@
/**
* Value to specify if Wi-Fi Wakeup feature is enabled.
+ *
+ * Type: int (0 for false, 1 for true)
* @hide
*/
@SystemApi
@@ -7654,6 +7656,8 @@
/**
* Value to specify if network recommendations from
* {@link com.android.server.NetworkScoreService} are enabled.
+ *
+ * Type: int (0 for false, 1 for true)
* @hide
*/
@SystemApi
@@ -8024,45 +8028,11 @@
public static final String PAC_CHANGE_DELAY = "pac_change_delay";
/**
- * Don't attempt to detect captive portals.
- *
- * @hide
- */
- public static final int CAPTIVE_PORTAL_MODE_IGNORE = 0;
-
- /**
- * When detecting a captive portal, display a notification that
- * prompts the user to sign in.
- *
- * @hide
- */
- public static final int CAPTIVE_PORTAL_MODE_PROMPT = 1;
-
- /**
- * When detecting a captive portal, immediately disconnect from the
- * network and do not reconnect to that network in the future.
- *
- * @hide
- */
- public static final int CAPTIVE_PORTAL_MODE_AVOID = 2;
-
- /**
- * What to do when connecting a network that presents a captive portal.
- * Must be one of the CAPTIVE_PORTAL_MODE_* constants above.
- *
- * The default for this setting is CAPTIVE_PORTAL_MODE_PROMPT.
- * @hide
- */
- public static final String CAPTIVE_PORTAL_MODE = "captive_portal_mode";
-
- /**
* Setting to turn off captive portal detection. Feature is enabled by
* default and the setting needs to be set to 0 to disable it.
*
- * @deprecated use CAPTIVE_PORTAL_MODE_IGNORE to disable captive portal detection
* @hide
*/
- @Deprecated
public static final String
CAPTIVE_PORTAL_DETECTION_ENABLED = "captive_portal_detection_enabled";
diff --git a/core/java/com/android/internal/os/TransferPipe.java b/core/java/com/android/internal/os/TransferPipe.java
index e76b395..f904150 100644
--- a/core/java/com/android/internal/os/TransferPipe.java
+++ b/core/java/com/android/internal/os/TransferPipe.java
@@ -16,6 +16,7 @@
package com.android.internal.os;
+import java.io.Closeable;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
@@ -32,13 +33,13 @@
/**
* Helper for transferring data through a pipe from a client app.
*/
-public final class TransferPipe implements Runnable {
+public final class TransferPipe implements Runnable, Closeable {
static final String TAG = "TransferPipe";
static final boolean DEBUG = false;
static final long DEFAULT_TIMEOUT = 5000; // 5 seconds
- final Thread mThread;;
+ final Thread mThread;
final ParcelFileDescriptor[] mFds;
FileDescriptor mOutFd;
@@ -54,8 +55,13 @@
}
public TransferPipe() throws IOException {
+ this(null);
+ }
+
+ public TransferPipe(String bufferPrefix) throws IOException {
mThread = new Thread(this, "TransferPipe");
mFds = ParcelFileDescriptor.createPipe();
+ mBufferPrefix = bufferPrefix;
}
ParcelFileDescriptor getReadFd() {
@@ -70,6 +76,11 @@
mBufferPrefix = prefix;
}
+ public static void dumpAsync(IBinder binder, FileDescriptor out, String[] args)
+ throws IOException, RemoteException {
+ goDump(binder, out, args);
+ }
+
static void go(Caller caller, IInterface iface, FileDescriptor out,
String prefix, String[] args) throws IOException, RemoteException {
go(caller, iface, out, prefix, args, DEFAULT_TIMEOUT);
@@ -86,12 +97,9 @@
return;
}
- TransferPipe tp = new TransferPipe();
- try {
+ try (TransferPipe tp = new TransferPipe()) {
caller.go(iface, tp.getWriteFd().getFileDescriptor(), prefix, args);
tp.go(out, timeout);
- } finally {
- tp.kill();
}
}
@@ -111,12 +119,9 @@
return;
}
- TransferPipe tp = new TransferPipe();
- try {
+ try (TransferPipe tp = new TransferPipe()) {
binder.dumpAsync(tp.getWriteFd().getFileDescriptor(), args);
tp.go(out, timeout);
- } finally {
- tp.kill();
}
}
@@ -173,6 +178,11 @@
}
}
+ @Override
+ public void close() {
+ kill();
+ }
+
public void kill() {
synchronized (this) {
closeFd(0);
diff --git a/core/tests/utiltests/Android.mk b/core/tests/utiltests/Android.mk
index 981be11..6d1ebb4 100644
--- a/core/tests/utiltests/Android.mk
+++ b/core/tests/utiltests/Android.mk
@@ -14,7 +14,6 @@
LOCAL_STATIC_JAVA_LIBRARIES := \
android-support-test \
- frameworks-base-testutils \
mockito-target
LOCAL_JAVA_LIBRARIES := android.test.runner
diff --git a/legacy-test/Android.mk b/legacy-test/Android.mk
index fe5d8ca..0011002 100644
--- a/legacy-test/Android.mk
+++ b/legacy-test/Android.mk
@@ -27,3 +27,15 @@
LOCAL_MODULE := legacy-test
include $(BUILD_JAVA_LIBRARY)
+
+ifeq ($(HOST_OS),linux)
+# Build the legacy-performance-test-hostdex library
+# =================================================
+# This contains the android.test.PerformanceTestCase class only
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := ../core/java/android/test/PerformanceTestCase.java
+LOCAL_MODULE := legacy-performance-test-hostdex
+
+include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
+endif # HOST_OS == linux
diff --git a/location/java/android/location/IFusedProvider.aidl b/location/java/android/location/IFusedProvider.aidl
index 8870d2a..e86ad1a 100644
--- a/location/java/android/location/IFusedProvider.aidl
+++ b/location/java/android/location/IFusedProvider.aidl
@@ -22,11 +22,11 @@
* Interface definition for Location providers that require FLP services.
* @hide
*/
-interface IFusedProvider {
+oneway interface IFusedProvider {
/**
* Provides access to a FusedLocationHardware instance needed for the provider to work.
*
* @param instance The FusedLocationHardware available for the provider to use.
*/
void onFusedLocationHardwareChange(in IFusedLocationHardware instance);
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index ca9a229..30edd9f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1813,14 +1813,11 @@
private void updateMtu(LinkProperties newLp, LinkProperties oldLp) {
final String iface = newLp.getInterfaceName();
final int mtu = newLp.getMtu();
- if (oldLp == null && mtu == 0) {
- // Silently ignore unset MTU value.
- return;
- }
if (oldLp != null && newLp.isIdenticalMtu(oldLp)) {
if (VDBG) log("identical MTU - not setting");
return;
}
+
if (LinkProperties.isValidMtu(mtu, newLp.hasGlobalIPv6Address()) == false) {
if (mtu != 0) loge("Unexpected mtu value: " + mtu + ", " + iface);
return;
@@ -2266,19 +2263,11 @@
synchronized (mNetworkForNetId) {
nai = mNetworkForNetId.get(netId);
}
- // If captive portal status has changed, update capabilities or disconnect.
+ // If captive portal status has changed, update capabilities.
if (nai != null && (visible != nai.lastCaptivePortalDetected)) {
final int oldScore = nai.getCurrentScore();
nai.lastCaptivePortalDetected = visible;
nai.everCaptivePortalDetected |= visible;
- if (nai.lastCaptivePortalDetected &&
- Settings.Global.CAPTIVE_PORTAL_MODE_AVOID == getCaptivePortalMode()) {
- if (DBG) log("Avoiding captive portal network: " + nai.name());
- nai.asyncChannel.sendMessage(
- NetworkAgent.CMD_PREVENT_AUTOMATIC_RECONNECT);
- teardownUnneededNetwork(nai);
- break;
- }
updateCapabilities(oldScore, nai, nai.networkCapabilities);
}
if (!visible) {
@@ -2299,12 +2288,6 @@
return true;
}
- private int getCaptivePortalMode() {
- return Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.CAPTIVE_PORTAL_MODE,
- Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
- }
-
private boolean maybeHandleNetworkAgentInfoMessage(Message msg) {
switch (msg.what) {
default:
@@ -2614,28 +2597,14 @@
"request NetworkCapabilities", ConnectivityManager.CALLBACK_CAP_CHANGED);
}
- private void handleTimedOutNetworkRequest(final NetworkRequestInfo nri) {
- if (mNetworkRequests.get(nri.request) != null && mNetworkForRequestId.get(
- nri.request.requestId) == null) {
- handleRemoveNetworkRequest(nri, ConnectivityManager.CALLBACK_UNAVAIL);
- }
- }
-
private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) {
final NetworkRequestInfo nri = getNriForAppRequest(
request, callingUid, "release NetworkRequest");
- if (nri != null) {
- handleRemoveNetworkRequest(nri, ConnectivityManager.CALLBACK_RELEASED);
- }
- }
+ if (nri == null) return;
- private void handleRemoveNetworkRequest(final NetworkRequestInfo nri, final int whichCallback) {
- final String logCallbackType = ConnectivityManager.getCallbackName(whichCallback);
- if (VDBG || (DBG && nri.request.isRequest())) {
- log("releasing " + nri.request + " (" + logCallbackType + ")");
- }
+ if (VDBG || (DBG && nri.request.isRequest())) log("releasing " + request);
nri.unlinkDeathRecipient();
- mNetworkRequests.remove(nri.request);
+ mNetworkRequests.remove(request);
synchronized (mUidToNetworkRequestCount) {
int requests = mUidToNetworkRequestCount.get(nri.mUid, 0);
if (requests < 1) {
@@ -2729,7 +2698,7 @@
}
}
}
- callCallbackForRequest(nri, null, whichCallback, 0);
+ callCallbackForRequest(nri, null, ConnectivityManager.CALLBACK_RELEASED, 0);
}
@Override
@@ -2966,11 +2935,6 @@
handleRegisterNetworkRequestWithIntent(msg);
break;
}
- case EVENT_TIMEOUT_NETWORK_REQUEST: {
- NetworkRequestInfo nri = (NetworkRequestInfo) msg.obj;
- handleTimedOutNetworkRequest(nri);
- break;
- }
case EVENT_RELEASE_NETWORK_REQUEST_WITH_INTENT: {
handleReleaseNetworkRequestWithIntent((PendingIntent) msg.obj, msg.arg1);
break;
diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java
index df1b6f5..3ad264d 100644
--- a/services/core/java/com/android/server/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/InputMethodManagerService.java
@@ -25,6 +25,7 @@
import com.android.internal.inputmethod.InputMethodUtils.InputMethodSettings;
import com.android.internal.os.HandlerCaller;
import com.android.internal.os.SomeArgs;
+import com.android.internal.os.TransferPipe;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethod;
@@ -4030,9 +4031,9 @@
if (client != null) {
pw.flush();
try {
- client.client.asBinder().dump(fd, args);
- } catch (RemoteException e) {
- p.println("Input method client dead: " + e);
+ TransferPipe.dumpAsync(client.client.asBinder(), fd, args);
+ } catch (IOException | RemoteException e) {
+ p.println("Failed to dump input method client: " + e);
}
} else {
p.println("No input method client.");
@@ -4046,9 +4047,9 @@
p.println(" ");
pw.flush();
try {
- focusedWindowClient.client.asBinder().dump(fd, args);
- } catch (RemoteException e) {
- p.println("Input method client in focused window dead: " + e);
+ TransferPipe.dumpAsync(focusedWindowClient.client.asBinder(), fd, args);
+ } catch (IOException | RemoteException e) {
+ p.println("Failed to dump input method client in focused window: " + e);
}
}
@@ -4056,9 +4057,9 @@
if (method != null) {
pw.flush();
try {
- method.asBinder().dump(fd, args);
- } catch (RemoteException e) {
- p.println("Input method service dead: " + e);
+ TransferPipe.dumpAsync(method.asBinder(), fd, args);
+ } catch (IOException | RemoteException e) {
+ p.println("Failed to dump input method service: " + e);
}
} else {
p.println("No input method service.");
diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java
index 4e969be..6412e01 100644
--- a/services/core/java/com/android/server/NetworkScoreService.java
+++ b/services/core/java/com/android/server/NetworkScoreService.java
@@ -36,25 +36,29 @@
import android.net.wifi.WifiConfiguration;
import android.os.Binder;
import android.os.IBinder;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.ArrayMap;
import android.util.Log;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.content.PackageMonitor;
+import com.android.internal.os.TransferPipe;
import java.io.FileDescriptor;
+import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Set;
+import java.util.function.Consumer;
/**
* Backing service for {@link android.net.NetworkScoreManager}.
@@ -66,7 +70,8 @@
private final Context mContext;
private final NetworkScorerAppManager mNetworkScorerAppManager;
- private final Map<Integer, INetworkScoreCache> mScoreCaches;
+ @GuardedBy("mScoreCaches")
+ private final Map<Integer, RemoteCallbackList<INetworkScoreCache>> mScoreCaches;
/** Lock used to update mPackageMonitor when scorer package changes occur. */
private final Object mPackageMonitorLock = new Object[0];
@@ -164,7 +169,7 @@
NetworkScoreService(Context context, NetworkScorerAppManager networkScoreAppManager) {
mContext = context;
mNetworkScorerAppManager = networkScoreAppManager;
- mScoreCaches = new HashMap<>();
+ mScoreCaches = new ArrayMap<>();
IntentFilter filter = new IntentFilter(Intent.ACTION_USER_UNLOCKED);
// TODO: Need to update when we support per-user scorers. http://b/23422763
mContext.registerReceiverAsUser(
@@ -274,7 +279,7 @@
}
// Separate networks by type.
- Map<Integer, List<ScoredNetwork>> networksByType = new HashMap<>();
+ Map<Integer, List<ScoredNetwork>> networksByType = new ArrayMap<>();
for (ScoredNetwork network : networks) {
List<ScoredNetwork> networkList = networksByType.get(network.networkKey.type);
if (networkList == null) {
@@ -285,19 +290,32 @@
}
// Pass the scores of each type down to the appropriate network scorer.
- for (Map.Entry<Integer, List<ScoredNetwork>> entry : networksByType.entrySet()) {
- INetworkScoreCache scoreCache = mScoreCaches.get(entry.getKey());
- if (scoreCache != null) {
- try {
- scoreCache.updateScores(entry.getValue());
- } catch (RemoteException e) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Unable to update scores of type " + entry.getKey(), e);
+ for (final Map.Entry<Integer, List<ScoredNetwork>> entry : networksByType.entrySet()) {
+ final RemoteCallbackList<INetworkScoreCache> callbackList;
+ final boolean isEmpty;
+ synchronized (mScoreCaches) {
+ callbackList = mScoreCaches.get(entry.getKey());
+ isEmpty = callbackList == null || callbackList.getRegisteredCallbackCount() == 0;
+ }
+ if (isEmpty) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "No scorer registered for type " + entry.getKey() + ", discarding");
+ }
+ continue;
+ }
+
+ sendCallback(new Consumer<INetworkScoreCache>() {
+ @Override
+ public void accept(INetworkScoreCache networkScoreCache) {
+ try {
+ networkScoreCache.updateScores(entry.getValue());
+ } catch (RemoteException e) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Unable to update scores of type " + entry.getKey(), e);
+ }
}
}
- } else if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "No scorer registered for type " + entry.getKey() + ", discarding");
- }
+ }, Collections.singleton(callbackList));
}
return true;
@@ -392,28 +410,52 @@
/** Clear scores. Callers are responsible for checking permissions as appropriate. */
private void clearInternal() {
- Set<INetworkScoreCache> cachesToClear = getScoreCaches();
-
- for (INetworkScoreCache scoreCache : cachesToClear) {
- try {
- scoreCache.clearScores();
- } catch (RemoteException e) {
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Unable to clear scores", e);
+ sendCallback(new Consumer<INetworkScoreCache>() {
+ @Override
+ public void accept(INetworkScoreCache networkScoreCache) {
+ try {
+ networkScoreCache.clearScores();
+ } catch (RemoteException e) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Unable to clear scores", e);
+ }
}
}
- }
+ }, getScoreCacheLists());
}
@Override
public void registerNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
synchronized (mScoreCaches) {
- if (mScoreCaches.containsKey(networkType)) {
- throw new IllegalArgumentException(
- "Score cache already registered for type " + networkType);
+ RemoteCallbackList<INetworkScoreCache> callbackList = mScoreCaches.get(networkType);
+ if (callbackList == null) {
+ callbackList = new RemoteCallbackList<>();
+ mScoreCaches.put(networkType, callbackList);
}
- mScoreCaches.put(networkType, scoreCache);
+ if (!callbackList.register(scoreCache)) {
+ if (callbackList.getRegisteredCallbackCount() == 0) {
+ mScoreCaches.remove(networkType);
+ }
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Unable to register NetworkScoreCache for type " + networkType);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void unregisterNetworkScoreCache(int networkType, INetworkScoreCache scoreCache) {
+ mContext.enforceCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED, TAG);
+ synchronized (mScoreCaches) {
+ RemoteCallbackList<INetworkScoreCache> callbackList = mScoreCaches.get(networkType);
+ if (callbackList == null || !callbackList.unregister(scoreCache)) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "Unable to unregister NetworkScoreCache for type " + networkType);
+ }
+ } else if (callbackList.getRegisteredCallbackCount() == 0) {
+ mScoreCaches.remove(networkType);
+ }
}
}
@@ -428,7 +470,7 @@
}
@Override
- protected void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+ protected void dump(final FileDescriptor fd, final PrintWriter writer, final String[] args) {
mContext.enforceCallingOrSelfPermission(permission.DUMP, TAG);
NetworkScorerAppData currentScorer = mNetworkScorerAppManager.getActiveScorer();
if (currentScorer == null) {
@@ -437,16 +479,17 @@
}
writer.println("Current scorer: " + currentScorer.mPackageName);
- for (INetworkScoreCache scoreCache : getScoreCaches()) {
- try {
- scoreCache.asBinder().dump(fd, args);
- } catch (RemoteException e) {
- writer.println("Unable to dump score cache");
- if (Log.isLoggable(TAG, Log.VERBOSE)) {
- Log.v(TAG, "Unable to dump score cache", e);
+ sendCallback(new Consumer<INetworkScoreCache>() {
+ @Override
+ public void accept(INetworkScoreCache networkScoreCache) {
+ try {
+ TransferPipe.dumpAsync(networkScoreCache.asBinder(), fd, args);
+ } catch (IOException | RemoteException e) {
+ writer.println("Failed to dump score cache: " + e);
}
}
- }
+ }, getScoreCacheLists());
+
if (mServiceConnection != null) {
mServiceConnection.dump(fd, writer, args);
} else {
@@ -456,14 +499,30 @@
}
/**
- * Returns a set of all score caches that are currently active.
+ * Returns a {@link Collection} of all {@link RemoteCallbackList}s that are currently active.
*
* <p>May be used to perform an action on all score caches without potentially strange behavior
* if a new scorer is registered during that action's execution.
*/
- private Set<INetworkScoreCache> getScoreCaches() {
+ private Collection<RemoteCallbackList<INetworkScoreCache>> getScoreCacheLists() {
synchronized (mScoreCaches) {
- return new HashSet<>(mScoreCaches.values());
+ return new ArrayList<>(mScoreCaches.values());
+ }
+ }
+
+ private void sendCallback(Consumer<INetworkScoreCache> consumer,
+ Collection<RemoteCallbackList<INetworkScoreCache>> remoteCallbackLists) {
+ for (RemoteCallbackList<INetworkScoreCache> callbackList : remoteCallbackLists) {
+ synchronized (callbackList) { // Ensure only one active broadcast per RemoteCallbackList
+ final int count = callbackList.beginBroadcast();
+ try {
+ for (int i = 0; i < count; i++) {
+ consumer.accept(callbackList.getBroadcastItem(i));
+ }
+ } finally {
+ callbackList.finishBroadcast();
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index c73d1dd..6eb89fa 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -211,9 +211,7 @@
private final NetworkRequest mDefaultRequest;
private final IpConnectivityLog mMetricsLog;
- @VisibleForTesting
- protected boolean mIsCaptivePortalCheckEnabled;
-
+ private boolean mIsCaptivePortalCheckEnabled;
private boolean mUseHttps;
// Set if the user explicitly selected "Do not use this network" in captive portal sign-in app.
@@ -267,8 +265,7 @@
setInitialState(mDefaultState);
mIsCaptivePortalCheckEnabled = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.CAPTIVE_PORTAL_MODE, Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT)
- != Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE;
+ Settings.Global.CAPTIVE_PORTAL_DETECTION_ENABLED, 1) == 1;
mUseHttps = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.CAPTIVE_PORTAL_USE_HTTPS, 1) == 1;
@@ -635,10 +632,7 @@
@VisibleForTesting
protected CaptivePortalProbeResult isCaptivePortal() {
- if (!mIsCaptivePortalCheckEnabled) {
- validationLog("Validation disabled.");
- return new CaptivePortalProbeResult(204);
- }
+ if (!mIsCaptivePortalCheckEnabled) return new CaptivePortalProbeResult(204);
URL pacUrl = null, httpsUrl = null, httpUrl = null, fallbackUrl = null;
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 6d96a10..0beb227 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -71,7 +71,6 @@
import com.android.internal.util.StateMachine;
import com.android.server.connectivity.tethering.IControlsTethering;
import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
-import com.android.server.connectivity.tethering.IPv6TetheringInterfaceServices;
import com.android.server.connectivity.tethering.TetherInterfaceStateMachine;
import com.android.server.net.BaseNetworkObserver;
@@ -1940,8 +1939,7 @@
private void trackNewTetherableInterface(String iface, int interfaceType) {
TetherState tetherState;
tetherState = new TetherState(new TetherInterfaceStateMachine(iface, mLooper,
- interfaceType, mNMService, mStatsService, this,
- new IPv6TetheringInterfaceServices(iface, mNMService)));
+ interfaceType, mNMService, mStatsService, this));
mTetherStates.put(iface, tetherState);
tetherState.mStateMachine.start();
}
diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
index dec2f77..c2c1a8c 100644
--- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
+++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
@@ -45,7 +45,7 @@
/**
* @hide
*/
-public class IPv6TetheringInterfaceServices {
+class IPv6TetheringInterfaceServices {
private static final String TAG = IPv6TetheringInterfaceServices.class.getSimpleName();
private static final IpPrefix LINK_LOCAL_PREFIX = new IpPrefix("fe80::/64");
private static final int RFC7421_IP_PREFIX_LENGTH = 64;
@@ -59,7 +59,7 @@
private RouterAdvertisementDaemon mRaDaemon;
private RaParams mLastRaParams;
- public IPv6TetheringInterfaceServices(String ifname, INetworkManagementService nms) {
+ IPv6TetheringInterfaceServices(String ifname, INetworkManagementService nms) {
mIfName = ifname;
mNMService = nms;
}
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index 37221a9..6ca4e27 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -94,14 +94,14 @@
public TetherInterfaceStateMachine(String ifaceName, Looper looper, int interfaceType,
INetworkManagementService nMService, INetworkStatsService statsService,
- IControlsTethering tetherController, IPv6TetheringInterfaceServices ipv6Svc) {
+ IControlsTethering tetherController) {
super(ifaceName, looper);
mNMService = nMService;
mStatsService = statsService;
mTetherController = tetherController;
mIfaceName = ifaceName;
mInterfaceType = interfaceType;
- mIPv6TetherSvc = ipv6Svc;
+ mIPv6TetherSvc = new IPv6TetheringInterfaceServices(mIfaceName, mNMService);
mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
mInitialState = new InitialState();
diff --git a/services/core/java/com/android/server/location/LocationProviderProxy.java b/services/core/java/com/android/server/location/LocationProviderProxy.java
index 5eb06ed..b44087c 100644
--- a/services/core/java/com/android/server/location/LocationProviderProxy.java
+++ b/services/core/java/com/android/server/location/LocationProviderProxy.java
@@ -17,6 +17,7 @@
package com.android.server.location;
import java.io.FileDescriptor;
+import java.io.IOException;
import java.io.PrintWriter;
import android.content.Context;
@@ -30,6 +31,7 @@
import com.android.internal.location.ProviderProperties;
import com.android.internal.location.ILocationProvider;
import com.android.internal.location.ProviderRequest;
+import com.android.internal.os.TransferPipe;
import com.android.server.LocationManagerService;
import com.android.server.ServiceWatcher;
@@ -230,14 +232,9 @@
pw.flush();
try {
- service.asBinder().dump(fd, args);
- } catch (RemoteException e) {
- pw.println("service down (RemoteException)");
- Log.w(TAG, e);
- } catch (Exception e) {
- pw.println("service down (Exception)");
- // never let remote service crash system server
- Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e);
+ TransferPipe.dumpAsync(service.asBinder(), fd, args);
+ } catch (IOException | RemoteException e) {
+ pw.println("Failed to dump location provider: " + e);
}
}
diff --git a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
index 68b465a..07d98bc 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolverConnection.java
@@ -32,7 +32,10 @@
import android.os.UserHandle;
import android.util.TimedRemoteCaller;
+import com.android.internal.os.TransferPipe;
+
import java.io.FileDescriptor;
+import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -85,13 +88,11 @@
.append((mRemoteInstance != null) ? "true" : "false").println();
pw.flush();
-
try {
- getRemoteInstanceLazy().asBinder().dump(fd, new String[] { prefix });
- } catch (TimeoutException te) {
- /* ignore */
- } catch (RemoteException re) {
- /* ignore */
+ TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), fd,
+ new String[] { prefix });
+ } catch (IOException | TimeoutException | RemoteException e) {
+ pw.println("Failed to dump remote instance: " + e);
}
}
}
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index d8f6b80..bff68d8 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -204,35 +204,70 @@
outputPath, dexFlags, compilerFilter, volumeUuid, sharedLibraries);
}
- public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
- return mInstaller.mergeProfiles(uid, pkgName);
+ public boolean mergeProfiles(int uid, String packageName) throws InstallerException {
+ checkLock();
+ try {
+ return mInstalld.mergeProfiles(uid, packageName);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
- public boolean dumpProfiles(String gid, String packageName, String codePaths)
+ public boolean dumpProfiles(int uid, String packageName, String codePaths)
throws InstallerException {
- return mInstaller.dumpProfiles(gid, packageName, codePaths);
+ checkLock();
+ try {
+ return mInstalld.dumpProfiles(uid, packageName, codePaths);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
public void idmap(String targetApkPath, String overlayApkPath, int uid)
throws InstallerException {
- mInstaller.execute("idmap", targetApkPath, overlayApkPath, uid);
+ checkLock();
+ try {
+ mInstalld.idmap(targetApkPath, overlayApkPath, uid);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
public void rmdex(String codePath, String instructionSet) throws InstallerException {
assertValidInstructionSet(instructionSet);
- mInstaller.execute("rmdex", codePath, instructionSet);
+ checkLock();
+ try {
+ mInstalld.rmdex(codePath, instructionSet);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
public void rmPackageDir(String packageDir) throws InstallerException {
- mInstaller.execute("rmpackagedir", packageDir);
+ checkLock();
+ try {
+ mInstalld.rmPackageDir(packageDir);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
- public void clearAppProfiles(String pkgName) throws InstallerException {
- mInstaller.execute("clear_app_profiles", pkgName);
+ public void clearAppProfiles(String packageName) throws InstallerException {
+ checkLock();
+ try {
+ mInstalld.clearAppProfiles(packageName);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
- public void destroyAppProfiles(String pkgName) throws InstallerException {
- mInstaller.execute("destroy_app_profiles", pkgName);
+ public void destroyAppProfiles(String packageName) throws InstallerException {
+ checkLock();
+ try {
+ mInstalld.destroyAppProfiles(packageName);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
public void createUserData(String uuid, int userId, int userSerial, int flags)
@@ -256,11 +291,21 @@
public void markBootComplete(String instructionSet) throws InstallerException {
assertValidInstructionSet(instructionSet);
- mInstaller.execute("markbootcomplete", instructionSet);
+ checkLock();
+ try {
+ mInstalld.markBootComplete(instructionSet);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
public void freeCache(String uuid, long freeStorageSize) throws InstallerException {
- mInstaller.execute("freecache", uuid, freeStorageSize);
+ checkLock();
+ try {
+ mInstalld.freeCache(uuid, freeStorageSize);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
/**
@@ -268,29 +313,54 @@
* directory to the real location for backward compatibility. Note that no
* such symlink is created for 64 bit shared libraries.
*/
- public void linkNativeLibraryDirectory(String uuid, String dataPath, String nativeLibPath32,
+ public void linkNativeLibraryDirectory(String uuid, String packageName, String nativeLibPath32,
int userId) throws InstallerException {
- mInstaller.execute("linklib", uuid, dataPath, nativeLibPath32, userId);
+ checkLock();
+ try {
+ mInstalld.linkNativeLibraryDirectory(uuid, packageName, nativeLibPath32, userId);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
public void createOatDir(String oatDir, String dexInstructionSet)
throws InstallerException {
- mInstaller.execute("createoatdir", oatDir, dexInstructionSet);
+ checkLock();
+ try {
+ mInstalld.createOatDir(oatDir, dexInstructionSet);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
public void linkFile(String relativePath, String fromBase, String toBase)
throws InstallerException {
- mInstaller.execute("linkfile", relativePath, fromBase, toBase);
+ checkLock();
+ try {
+ mInstalld.linkFile(relativePath, fromBase, toBase);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
public void moveAb(String apkPath, String instructionSet, String outputPath)
throws InstallerException {
- mInstaller.execute("move_ab", apkPath, instructionSet, outputPath);
+ checkLock();
+ try {
+ mInstalld.moveAb(apkPath, instructionSet, outputPath);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
public void deleteOdex(String apkPath, String instructionSet, String outputPath)
throws InstallerException {
- mInstaller.execute("delete_odex", apkPath, instructionSet, outputPath);
+ checkLock();
+ try {
+ mInstalld.deleteOdex(apkPath, instructionSet, outputPath);
+ } catch (RemoteException | ServiceSpecificException e) {
+ throw new InstallerException(e.getMessage());
+ }
}
private static void assertValidInstructionSet(String instructionSet)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 56a0173..9102fee 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7530,9 +7530,8 @@
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
try {
List<String> allCodePaths = pkg.getAllCodePathsExcludingResourceOnly();
- String gid = Integer.toString(sharedGid);
String codePaths = TextUtils.join(";", allCodePaths);
- mInstaller.dumpProfiles(gid, packageName, codePaths);
+ mInstaller.dumpProfiles(sharedGid, packageName, codePaths);
} catch (InstallerException e) {
Slog.w(TAG, "Failed to dump profiles", e);
}
diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index a8356dc..4c75452 100644
--- a/services/net/java/android/net/apf/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -283,20 +283,14 @@
mReceiveThread.start();
}
- // Returns seconds since device boot.
+ // Returns seconds since Unix Epoch.
+ // TODO: use SystemClock.elapsedRealtime() instead
private static long curTime() {
- return SystemClock.elapsedRealtime() / DateUtils.SECOND_IN_MILLIS;
- }
-
- public static class InvalidRaException extends Exception {
- public InvalidRaException(String m) {
- super(m);
- }
+ return System.currentTimeMillis() / DateUtils.SECOND_IN_MILLIS;
}
// A class to hold information about an RA.
- @VisibleForTesting
- class Ra {
+ private class Ra {
// From RFC4861:
private static final int ICMP6_RA_HEADER_LEN = 16;
private static final int ICMP6_RA_CHECKSUM_OFFSET =
@@ -368,7 +362,7 @@
} catch (UnsupportedOperationException e) {
// array() failed. Cannot happen, mPacket is array-backed and read-write.
return "???";
- } catch (ClassCastException|UnknownHostException e) {
+ } catch (ClassCastException | UnknownHostException e) {
// Cannot happen.
return "???";
}
@@ -378,16 +372,16 @@
// TODO: Make this static once RA is its own class.
private void prefixOptionToString(StringBuffer sb, int offset) {
String prefix = IPv6AddresstoString(offset + 16);
- int length = getUint8(mPacket, offset + 2);
- long valid = getUint32(mPacket, offset + 4);
- long preferred = getUint32(mPacket, offset + 8);
+ int length = uint8(mPacket.get(offset + 2));
+ long valid = mPacket.getInt(offset + 4);
+ long preferred = mPacket.getInt(offset + 8);
sb.append(String.format("%s/%d %ds/%ds ", prefix, length, valid, preferred));
}
private void rdnssOptionToString(StringBuffer sb, int offset) {
- int optLen = getUint8(mPacket, offset + 1) * 8;
+ int optLen = uint8(mPacket.get(offset + 1)) * 8;
if (optLen < 24) return; // Malformed or empty.
- long lifetime = getUint32(mPacket, offset + 4);
+ long lifetime = uint32(mPacket.getInt(offset + 4));
int numServers = (optLen - 8) / 16;
sb.append("DNS ").append(lifetime).append("s");
for (int server = 0; server < numServers; server++) {
@@ -401,7 +395,7 @@
sb.append(String.format("RA %s -> %s %ds ",
IPv6AddresstoString(IPV6_SRC_ADDR_OFFSET),
IPv6AddresstoString(IPV6_DEST_ADDR_OFFSET),
- getUint16(mPacket, ICMP6_RA_ROUTER_LIFETIME_OFFSET)));
+ uint16(mPacket.getShort(ICMP6_RA_ROUTER_LIFETIME_OFFSET))));
for (int i: mPrefixOptionOffsets) {
prefixOptionToString(sb, i);
}
@@ -409,7 +403,7 @@
rdnssOptionToString(sb, i);
}
return sb.toString();
- } catch (BufferUnderflowException|IndexOutOfBoundsException e) {
+ } catch (BufferUnderflowException | IndexOutOfBoundsException e) {
return "<Malformed RA>";
}
}
@@ -442,20 +436,16 @@
// Buffer.position(int) or due to an invalid-length option) or IndexOutOfBoundsException
// (from ByteBuffer.get(int) ) if parsing encounters something non-compliant with
// specifications.
- Ra(byte[] packet, int length) throws InvalidRaException {
- if (length < ICMP6_RA_OPTION_OFFSET) {
- throw new InvalidRaException("Not an ICMP6 router advertisement");
- }
-
+ Ra(byte[] packet, int length) {
mPacket = ByteBuffer.wrap(Arrays.copyOf(packet, length));
mLastSeen = curTime();
// Sanity check packet in case a packet arrives before we attach RA filter
// to our packet socket. b/29586253
if (getUint16(mPacket, ETH_ETHERTYPE_OFFSET) != ETH_P_IPV6 ||
- getUint8(mPacket, IPV6_NEXT_HEADER_OFFSET) != IPPROTO_ICMPV6 ||
- getUint8(mPacket, ICMP6_TYPE_OFFSET) != ICMP6_ROUTER_ADVERTISEMENT) {
- throw new InvalidRaException("Not an ICMP6 router advertisement");
+ uint8(mPacket.get(IPV6_NEXT_HEADER_OFFSET)) != IPPROTO_ICMPV6 ||
+ uint8(mPacket.get(ICMP6_TYPE_OFFSET)) != ICMP6_ROUTER_ADVERTISEMENT) {
+ throw new IllegalArgumentException("Not an ICMP6 router advertisement");
}
@@ -476,8 +466,8 @@
mPacket.position(ICMP6_RA_OPTION_OFFSET);
while (mPacket.hasRemaining()) {
final int position = mPacket.position();
- final int optionType = getUint8(mPacket, position);
- final int optionLength = getUint8(mPacket, position + 1) * 8;
+ final int optionType = uint8(mPacket.get(position));
+ final int optionLength = uint8(mPacket.get(position + 1)) * 8;
long lifetime;
switch (optionType) {
case ICMP6_PREFIX_OPTION_TYPE:
@@ -521,7 +511,7 @@
break;
}
if (optionLength <= 0) {
- throw new InvalidRaException(String.format(
+ throw new IllegalArgumentException(String.format(
"Invalid option length opt=%d len=%d", optionType, optionLength));
}
mPacket.position(position + optionLength);
@@ -562,10 +552,10 @@
final long optionLifetime;
switch (lifetimeLength) {
case 2:
- optionLifetime = getUint16(byteBuffer, offset);
+ optionLifetime = uint16(byteBuffer.getShort(offset));
break;
case 4:
- optionLifetime = getUint32(byteBuffer, offset);
+ optionLifetime = uint32(byteBuffer.getInt(offset));
break;
default:
throw new IllegalStateException("bogus lifetime size " + lifetimeLength);
@@ -935,8 +925,8 @@
// Execution will reach the end of the program if no filters match, which will pass the
// packet to the AP.
program = gen.generate();
- } catch (IllegalInstructionException|IllegalStateException e) {
- Log.e(TAG, "Failed to generate APF program.", e);
+ } catch (IllegalInstructionException e) {
+ Log.e(TAG, "Program failed to generate: ", e);
return;
}
mLastTimeInstalledProgram = curTime();
@@ -982,8 +972,7 @@
* if the current APF program should be updated.
* @return a ProcessRaResult enum describing what action was performed.
*/
- @VisibleForTesting
- synchronized ProcessRaResult processRa(byte[] packet, int length) {
+ private synchronized ProcessRaResult processRa(byte[] packet, int length) {
if (VDBG) hexDump("Read packet = ", packet, length);
// Have we seen this RA before?
@@ -1022,7 +1011,7 @@
try {
ra = new Ra(packet, length);
} catch (Exception e) {
- Log.e(TAG, "Error parsing RA", e);
+ Log.e(TAG, "Error parsing RA: " + e);
return ProcessRaResult.PARSE_ERROR;
}
// Ignore 0 lifetime RAs.
@@ -1161,11 +1150,7 @@
return i & 0xffffffffL;
}
- private static int getUint8(ByteBuffer buffer, int position) {
- return uint8(buffer.get(position));
- }
-
- private static int getUint16(ByteBuffer buffer, int position) {
+ private static long getUint16(ByteBuffer buffer, int position) {
return uint16(buffer.getShort(position));
}
diff --git a/services/net/java/android/net/ip/IpReachabilityMonitor.java b/services/net/java/android/net/ip/IpReachabilityMonitor.java
index a883e28..a6bb40c 100644
--- a/services/net/java/android/net/ip/IpReachabilityMonitor.java
+++ b/services/net/java/android/net/ip/IpReachabilityMonitor.java
@@ -50,9 +50,9 @@
import java.net.SocketAddress;
import java.net.SocketException;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -163,7 +163,8 @@
private Map<InetAddress, Short> mIpWatchList = new HashMap<>();
@GuardedBy("mLock")
private int mIpWatchListVersion;
- private volatile boolean mRunning;
+ @GuardedBy("mLock")
+ private boolean mRunning;
// Time in milliseconds of the last forced probe request.
private volatile long mLastProbeTimeMs;
@@ -245,7 +246,7 @@
}
public void stop() {
- mRunning = false;
+ synchronized (mLock) { mRunning = false; }
clearLinkProperties();
mNetlinkSocketObserver.clearNetlinkSocket();
}
@@ -280,6 +281,12 @@
}
}
+ private boolean stillRunning() {
+ synchronized (mLock) {
+ return mRunning;
+ }
+ }
+
private static boolean isOnLink(List<RouteInfo> routes, InetAddress ip) {
for (RouteInfo route : routes) {
if (!route.hasGateway() && route.matches(ip)) {
@@ -383,12 +390,12 @@
}
public void probeAll() {
- final List<InetAddress> ipProbeList;
+ Set<InetAddress> ipProbeList = new HashSet<InetAddress>();
synchronized (mLock) {
- ipProbeList = new ArrayList<>(mIpWatchList.keySet());
+ ipProbeList.addAll(mIpWatchList.keySet());
}
- if (!ipProbeList.isEmpty() && mRunning) {
+ if (!ipProbeList.isEmpty() && stillRunning()) {
// Keep the CPU awake long enough to allow all ARP/ND
// probes a reasonable chance at success. See b/23197666.
//
@@ -399,7 +406,7 @@
}
for (InetAddress target : ipProbeList) {
- if (!mRunning) {
+ if (!stillRunning()) {
break;
}
final int returnValue = probeNeighbor(mInterfaceIndex, target);
@@ -444,21 +451,21 @@
@Override
public void run() {
if (VDBG) { Log.d(TAG, "Starting observing thread."); }
- mRunning = true;
+ synchronized (mLock) { mRunning = true; }
try {
setupNetlinkSocket();
} catch (ErrnoException | SocketException e) {
Log.e(TAG, "Failed to suitably initialize a netlink socket", e);
- mRunning = false;
+ synchronized (mLock) { mRunning = false; }
}
- while (mRunning) {
- final ByteBuffer byteBuffer;
+ ByteBuffer byteBuffer;
+ while (stillRunning()) {
try {
byteBuffer = recvKernelReply();
} catch (ErrnoException e) {
- if (mRunning) { Log.w(TAG, "ErrnoException: ", e); }
+ if (stillRunning()) { Log.w(TAG, "ErrnoException: ", e); }
break;
}
final long whenMs = SystemClock.elapsedRealtime();
@@ -470,7 +477,7 @@
clearNetlinkSocket();
- mRunning = false; // Not a no-op when ErrnoException happened.
+ synchronized (mLock) { mRunning = false; }
if (VDBG) { Log.d(TAG, "Finishing observing thread."); }
}
diff --git a/services/print/java/com/android/server/print/RemotePrintSpooler.java b/services/print/java/com/android/server/print/RemotePrintSpooler.java
index 07b26e8..6b919df 100644
--- a/services/print/java/com/android/server/print/RemotePrintSpooler.java
+++ b/services/print/java/com/android/server/print/RemotePrintSpooler.java
@@ -43,9 +43,12 @@
import android.util.Slog;
import android.util.TimedRemoteCaller;
+import com.android.internal.os.TransferPipe;
+
import libcore.io.IoUtils;
import java.io.FileDescriptor;
+import java.io.IOException;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.List;
@@ -572,13 +575,11 @@
.append((mRemoteInstance != null) ? "true" : "false").println();
pw.flush();
-
try {
- getRemoteInstanceLazy().asBinder().dump(fd, new String[]{prefix});
- } catch (TimeoutException te) {
- /* ignore */
- } catch (RemoteException re) {
- /* ignore */
+ TransferPipe.dumpAsync(getRemoteInstanceLazy().asBinder(), fd,
+ new String[] { prefix });
+ } catch (IOException | TimeoutException | RemoteException e) {
+ pw.println("Failed to dump remote instance: " + e);
}
}
}
diff --git a/tests/net/jni/UidRangeTest.cpp b/services/tests/servicestests/jni/UidRangeTest.cpp
similarity index 100%
rename from tests/net/jni/UidRangeTest.cpp
rename to services/tests/servicestests/jni/UidRangeTest.cpp
diff --git a/tests/net/jni/UidRangeTest.h b/services/tests/servicestests/jni/UidRangeTest.h
similarity index 100%
rename from tests/net/jni/UidRangeTest.h
rename to services/tests/servicestests/jni/UidRangeTest.h
diff --git a/tests/net/jni/apf_jni.cpp b/services/tests/servicestests/jni/apf_jni.cpp
similarity index 100%
rename from tests/net/jni/apf_jni.cpp
rename to services/tests/servicestests/jni/apf_jni.cpp
diff --git a/tests/net/res/raw/apf.pcap b/services/tests/servicestests/res/raw/apf.pcap
similarity index 100%
rename from tests/net/res/raw/apf.pcap
rename to services/tests/servicestests/res/raw/apf.pcap
Binary files differ
diff --git a/tests/net/java/android/net/ConnectivityMetricsLoggerTest.java b/services/tests/servicestests/src/android/net/ConnectivityMetricsLoggerTest.java
similarity index 100%
rename from tests/net/java/android/net/ConnectivityMetricsLoggerTest.java
rename to services/tests/servicestests/src/android/net/ConnectivityMetricsLoggerTest.java
diff --git a/tests/net/java/android/net/UidRangeTest.java b/services/tests/servicestests/src/android/net/UidRangeTest.java
similarity index 98%
rename from tests/net/java/android/net/UidRangeTest.java
rename to services/tests/servicestests/src/android/net/UidRangeTest.java
index 0a56e1b..221fe0f 100644
--- a/tests/net/java/android/net/UidRangeTest.java
+++ b/services/tests/servicestests/src/android/net/UidRangeTest.java
@@ -26,7 +26,7 @@
public class UidRangeTest extends TestCase {
static {
- System.loadLibrary("frameworksnettestsjni");
+ System.loadLibrary("servicestestsjni");
}
private static native byte[] readAndWriteNative(byte[] inParcel);
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/services/tests/servicestests/src/android/net/apf/ApfTest.java
similarity index 96%
rename from tests/net/java/android/net/apf/ApfTest.java
rename to services/tests/servicestests/src/android/net/apf/ApfTest.java
index 81f66a5..f7c61d1 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/services/tests/servicestests/src/android/net/apf/ApfTest.java
@@ -16,6 +16,10 @@
package android.net.apf;
+import static android.system.OsConstants.*;
+
+import com.android.frameworks.servicestests.R;
+
import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkUtils;
@@ -32,12 +36,7 @@
import android.system.ErrnoException;
import android.system.Os;
import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import static android.system.OsConstants.*;
-
-import com.android.frameworks.tests.net.R;
-import com.android.internal.util.HexDump;
+import android.test.suitebuilder.annotation.LargeTest;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
@@ -55,7 +54,6 @@
import java.net.NetworkInterface;
import java.nio.ByteBuffer;
import java.util.List;
-import java.util.Random;
import libcore.io.IoUtils;
import libcore.io.Streams;
@@ -76,7 +74,7 @@
super.setUp();
MockitoAnnotations.initMocks(this);
// Load up native shared library containing APF interpreter exposed via JNI.
- System.loadLibrary("frameworksnettestsjni");
+ System.loadLibrary("servicestestsjni");
}
// Expected return codes from APF interpreter.
@@ -155,7 +153,7 @@
* generating bytecode for that program and running it through the
* interpreter to verify it functions correctly.
*/
- @MediumTest
+ @LargeTest
public void testApfInstructions() throws IllegalInstructionException {
// Empty program should pass because having the program counter reach the
// location immediately after the program indicates the packet should be
@@ -563,7 +561,7 @@
* 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.
*/
- @MediumTest
+ @LargeTest
public void testApfAgainstBpf() throws Exception {
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",
@@ -721,7 +719,7 @@
private static final byte[] ANOTHER_IPV4_ADDR = {10, 0, 0, 2};
private static final byte[] IPV4_ANY_HOST_ADDR = {0, 0, 0, 0};
- @MediumTest
+ @LargeTest
public void testApfFilterIPv4() throws Exception {
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_IPV4_ADDR), 19);
@@ -776,7 +774,7 @@
apfFilter.shutdown();
}
- @MediumTest
+ @LargeTest
public void testApfFilterIPv6() throws Exception {
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog);
@@ -802,7 +800,7 @@
apfFilter.shutdown();
}
- @MediumTest
+ @LargeTest
public void testApfFilterMulticast() throws Exception {
final byte[] unicastIpv4Addr = {(byte)192,0,2,63};
final byte[] broadcastIpv4Addr = {(byte)192,0,2,(byte)255};
@@ -912,7 +910,7 @@
assertDrop(program, garpReply());
}
- @MediumTest
+ @LargeTest
public void testApfFilterArp() throws Exception {
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
ApfFilter apfFilter = new TestApfFilter(ipManagerCallback, ALLOW_MULTICAST, mLog);
@@ -1031,7 +1029,7 @@
ipManagerCallback.assertNoProgramUpdate();
}
- @MediumTest
+ @LargeTest
public void testApfFilterRa() throws Exception {
MockIpManagerCallback ipManagerCallback = new MockIpManagerCallback();
TestApfFilter apfFilter = new TestApfFilter(ipManagerCallback, DROP_MULTICAST, mLog);
@@ -1148,41 +1146,6 @@
buffer.position(original);
}
- @SmallTest
- public void testRaParsing() throws Exception {
- final int maxRandomPacketSize = 512;
- final Random r = new Random();
- MockIpManagerCallback cb = new MockIpManagerCallback();
- TestApfFilter apfFilter = new TestApfFilter(cb, DROP_MULTICAST, mLog);
- for (int i = 0; i < 1000; i++) {
- byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
- r.nextBytes(packet);
- try {
- apfFilter.new Ra(packet, packet.length);
- } catch (ApfFilter.InvalidRaException e) {
- } catch (Exception e) {
- throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
- }
- }
- }
-
- @SmallTest
- public void testRaProcessing() throws Exception {
- final int maxRandomPacketSize = 512;
- final Random r = new Random();
- MockIpManagerCallback cb = new MockIpManagerCallback();
- TestApfFilter apfFilter = new TestApfFilter(cb, DROP_MULTICAST, mLog);
- for (int i = 0; i < 1000; i++) {
- byte[] packet = new byte[r.nextInt(maxRandomPacketSize + 1)];
- r.nextBytes(packet);
- try {
- apfFilter.processRa(packet, packet.length);
- } catch (Exception e) {
- throw new Exception("bad packet: " + HexDump.toHexString(packet), e);
- }
- }
- }
-
/**
* Call the APF interpreter the run {@code program} on {@code packet} pretending the
* filter was installed {@code filter_age} seconds ago.
@@ -1204,7 +1167,6 @@
private native static boolean compareBpfApf(String filter, String pcap_filename,
byte[] apf_program);
- @SmallTest
public void testBytesToInt() {
assertEquals(0x00000000, ApfFilter.bytesToInt(IPV4_ANY_HOST_ADDR));
assertEquals(0xffffffff, ApfFilter.bytesToInt(IPV4_BROADCAST_ADDRESS));
diff --git a/tests/net/java/android/net/apf/Bpf2Apf.java b/services/tests/servicestests/src/android/net/apf/Bpf2Apf.java
similarity index 100%
rename from tests/net/java/android/net/apf/Bpf2Apf.java
rename to services/tests/servicestests/src/android/net/apf/Bpf2Apf.java
diff --git a/tests/net/java/android/net/dhcp/DhcpPacketTest.java b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
similarity index 100%
rename from tests/net/java/android/net/dhcp/DhcpPacketTest.java
rename to services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
diff --git a/tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java b/services/tests/servicestests/src/android/net/netlink/NetlinkErrorMessageTest.java
similarity index 100%
rename from tests/net/java/android/net/netlink/NetlinkErrorMessageTest.java
rename to services/tests/servicestests/src/android/net/netlink/NetlinkErrorMessageTest.java
diff --git a/tests/net/java/android/net/netlink/NetlinkSocketTest.java b/services/tests/servicestests/src/android/net/netlink/NetlinkSocketTest.java
similarity index 100%
rename from tests/net/java/android/net/netlink/NetlinkSocketTest.java
rename to services/tests/servicestests/src/android/net/netlink/NetlinkSocketTest.java
diff --git a/tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java b/services/tests/servicestests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java
similarity index 100%
rename from tests/net/java/android/net/netlink/RtNetlinkNeighborMessageTest.java
rename to services/tests/servicestests/src/android/net/netlink/RtNetlinkNeighborMessageTest.java
diff --git a/tests/net/java/android/net/util/IpUtilsTest.java b/services/tests/servicestests/src/android/net/util/IpUtilsTest.java
similarity index 100%
rename from tests/net/java/android/net/util/IpUtilsTest.java
rename to services/tests/servicestests/src/android/net/util/IpUtilsTest.java
diff --git a/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java b/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProvider.java
similarity index 98%
rename from tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
rename to services/tests/servicestests/src/com/android/internal/util/FakeSettingsProvider.java
index 8ca849b..808f4dd 100644
--- a/tests/utils/testutils/java/com/android/internal/util/test/FakeSettingsProvider.java
+++ b/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProvider.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.util.test;
+package com.android.internal.util;
import android.net.Uri;
import android.os.Bundle;
diff --git a/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java b/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProviderTest.java
similarity index 97%
rename from core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java
rename to services/tests/servicestests/src/com/android/internal/util/FakeSettingsProviderTest.java
index f2be109..05de0a5 100644
--- a/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java
+++ b/services/tests/servicestests/src/com/android/internal/util/FakeSettingsProviderTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.util.test;
+package com.android.internal.util;
import android.content.ContentResolver;
import android.database.ContentObserver;
diff --git a/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
similarity index 89%
rename from tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java
rename to services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
index 27b7419..13657ab 100644
--- a/tests/utils/testutils/java/com/android/internal/util/test/BroadcastInterceptingContext.java
+++ b/services/tests/servicestests/src/com/android/server/BroadcastInterceptingContext.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.internal.util.test;
+package com.android.server;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -25,12 +25,13 @@
import android.os.Handler;
import android.os.UserHandle;
-import java.util.ArrayList;
+import com.google.common.collect.Lists;
+import com.google.common.util.concurrent.AbstractFuture;
+
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
-import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
@@ -41,17 +42,9 @@
public class BroadcastInterceptingContext extends ContextWrapper {
private static final String TAG = "WatchingContext";
- private final List<BroadcastInterceptor> mInterceptors = new ArrayList<>();
+ private final List<BroadcastInterceptor> mInterceptors = Lists.newArrayList();
- public abstract class FutureIntent extends FutureTask<Intent> {
- public FutureIntent() {
- super(
- () -> { throw new IllegalStateException("Cannot happen"); }
- );
- }
- }
-
- public class BroadcastInterceptor extends FutureIntent {
+ public class BroadcastInterceptor extends AbstractFuture<Intent> {
private final BroadcastReceiver mReceiver;
private final IntentFilter mFilter;
@@ -89,11 +82,11 @@
super(base);
}
- public FutureIntent nextBroadcastIntent(String action) {
+ public Future<Intent> nextBroadcastIntent(String action) {
return nextBroadcastIntent(new IntentFilter(action));
}
- public FutureIntent nextBroadcastIntent(IntentFilter filter) {
+ public Future<Intent> nextBroadcastIntent(IntentFilter filter) {
final BroadcastInterceptor interceptor = new BroadcastInterceptor(null, filter);
synchronized (mInterceptors) {
mInterceptors.add(interceptor);
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
similarity index 94%
rename from tests/net/java/com/android/server/ConnectivityServiceTest.java
rename to services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
index 885e8a7..4af1cf1 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java
@@ -68,16 +68,14 @@
import android.os.SystemClock;
import android.provider.Settings;
import android.test.AndroidTestCase;
-import android.test.FlakyTest;
import android.test.mock.MockContentResolver;
import android.test.suitebuilder.annotation.LargeTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
import android.util.LogPrinter;
+import com.android.internal.util.FakeSettingsProvider;
import com.android.internal.util.WakeupMessage;
-import com.android.internal.util.test.BroadcastInterceptingContext;
-import com.android.internal.util.test.FakeSettingsProvider;
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkMonitor;
import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult;
@@ -217,20 +215,8 @@
mService.waitForIdle();
assertEquals(i, mCm.getNetworkCapabilities(n).getSignalStrength());
}
- }
-
- @FlakyTest(tolerance = 3)
- public void testNotWaitingForIdleCausesRaceConditions() {
- // Bring up a network that we can use to send messages to ConnectivityService.
- ConditionVariable cv = waitForConnectivityBroadcasts(1);
- mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
- mWiFiNetworkAgent.connect(false);
- waitFor(cv);
- Network n = mWiFiNetworkAgent.getNetwork();
- assertNotNull(n);
// Ensure that not calling waitForIdle causes a race condition.
- final int attempts = 50; // Causes the test to take about 200ms on bullhead-eng.
for (int i = 0; i < attempts; i++) {
mWiFiNetworkAgent.setSignalStrength(i);
if (i != mCm.getNetworkCapabilities(n).getSignalStrength()) {
@@ -250,7 +236,6 @@
private final IdleableHandlerThread mHandlerThread;
private final ConditionVariable mDisconnected = new ConditionVariable();
private final ConditionVariable mNetworkStatusReceived = new ConditionVariable();
- private final ConditionVariable mPreventReconnectReceived = new ConditionVariable();
private int mScore;
private NetworkAgent mNetworkAgent;
private int mStartKeepaliveError = PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED;
@@ -306,11 +291,6 @@
mRedirectUrl = redirectUrl;
mNetworkStatusReceived.open();
}
-
- @Override
- protected void preventAutomaticReconnect() {
- mPreventReconnectReceived.open();
- }
};
// Waits for the NetworkAgent to be registered, which includes the creation of the
// NetworkMonitor.
@@ -395,6 +375,11 @@
mWrappedNetworkMonitor.gen204ProbeResult = 200;
mWrappedNetworkMonitor.gen204ProbeRedirectUrl = redirectUrl;
connect(false);
+ waitFor(new Criteria() { public boolean get() {
+ NetworkCapabilities caps = mCm.getNetworkCapabilities(getNetwork());
+ return caps != null && caps.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL);} });
+ mWrappedNetworkMonitor.gen204ProbeResult = 500;
+ mWrappedNetworkMonitor.gen204ProbeRedirectUrl = null;
}
public void disconnect() {
@@ -406,10 +391,6 @@
return new Network(mNetworkAgent.netId);
}
- public ConditionVariable getPreventReconnectReceived() {
- return mPreventReconnectReceived;
- }
-
public ConditionVariable getDisconnectedCV() {
return mDisconnected;
}
@@ -616,7 +597,6 @@
@Override
protected CaptivePortalProbeResult isCaptivePortal() {
- if (!mIsCaptivePortalCheckEnabled) { return new CaptivePortalProbeResult(204); }
return new CaptivePortalProbeResult(gen204ProbeResult, gen204ProbeRedirectUrl, null);
}
}
@@ -763,9 +743,6 @@
mService.systemReady();
mCm = new WrappedConnectivityManager(getContext(), mService);
mCm.bindProcessToNetwork(null);
-
- // Ensure that the default setting for Captive Portals is used for most tests
- setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_PROMPT);
}
public void tearDown() throws Exception {
@@ -1100,8 +1077,7 @@
NETWORK_CAPABILITIES,
LINK_PROPERTIES,
LOSING,
- LOST,
- UNAVAILABLE
+ LOST
}
/**
@@ -1142,11 +1118,6 @@
}
@Override
- public void onUnavailable() {
- setLastCallback(CallbackState.UNAVAILABLE, null, null);
- }
-
- @Override
public void onLosing(Network network, int maxMsToLive) {
setLastCallback(CallbackState.LOSING, network, maxMsToLive /* autoboxed int */);
}
@@ -1733,47 +1704,6 @@
validatedCallback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
}
- @LargeTest
- public void testAvoidOrIgnoreCaptivePortals() {
- final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
- final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
- .addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
- mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
-
- final TestNetworkCallback validatedCallback = new TestNetworkCallback();
- final NetworkRequest validatedRequest = new NetworkRequest.Builder()
- .addCapability(NET_CAPABILITY_VALIDATED).build();
- mCm.registerNetworkCallback(validatedRequest, validatedCallback);
-
- setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_AVOID);
- // Bring up a network with a captive portal.
- // Expect it to fail to connect and not result in any callbacks.
- mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
- String firstRedirectUrl = "http://example.com/firstPath";
-
- ConditionVariable disconnectCv = mWiFiNetworkAgent.getDisconnectedCV();
- ConditionVariable avoidCv = mWiFiNetworkAgent.getPreventReconnectReceived();
- mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
- waitFor(disconnectCv);
- waitFor(avoidCv);
-
- assertNoCallbacks(captivePortalCallback, validatedCallback);
-
- // Now test ignore mode.
- setCaptivePortalMode(Settings.Global.CAPTIVE_PORTAL_MODE_IGNORE);
-
- // Bring up a network with a captive portal.
- // Since we're ignoring captive portals, the network will validate.
- mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
- String secondRedirectUrl = "http://example.com/secondPath";
- mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl);
-
- // Expect NET_CAPABILITY_VALIDATED onAvailable callback.
- validatedCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
- // But there should be no CaptivePortal callback.
- captivePortalCallback.assertNoCallback();
- }
-
@SmallTest
public void testInvalidNetworkSpecifier() {
boolean execptionCalled = true;
@@ -1914,11 +1844,6 @@
mCm.unregisterNetworkCallback(cellNetworkCallback);
}
- private void setCaptivePortalMode(int mode) {
- ContentResolver cr = mServiceContext.getContentResolver();
- Settings.Global.putInt(cr, Settings.Global.CAPTIVE_PORTAL_MODE, mode);
- }
-
private void setMobileDataAlwaysOn(boolean enable) {
ContentResolver cr = mServiceContext.getContentResolver();
Settings.Global.putInt(cr, Settings.Global.MOBILE_DATA_ALWAYS_ON, enable ? 1 : 0);
@@ -2296,79 +2221,6 @@
mCm.unregisterNetworkCallback(defaultCallback);
}
- /**
- * Validate that a satisfied network request does not trigger onUnavailable() once the
- * time-out period expires.
- */
- @SmallTest
- public void testSatisfiedNetworkRequestDoesNotTriggerOnUnavailable() {
- NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
- NetworkCapabilities.TRANSPORT_WIFI).build();
- final TestNetworkCallback networkCallback = new TestNetworkCallback();
- mCm.requestNetwork(nr, networkCallback, 10);
-
- mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
- mWiFiNetworkAgent.connect(false);
- networkCallback.expectCallback(CallbackState.AVAILABLE, mWiFiNetworkAgent);
-
- // pass timeout and validate that UNAVAILABLE is not called
- try {
- Thread.sleep(15);
- } catch (InterruptedException e) {
- }
- networkCallback.assertNoCallback();
- }
-
- /**
- * Validate that when a time-out is specified for a network request the onUnavailable()
- * callback is called when time-out expires. Then validate that if network request is
- * (somehow) satisfied - the callback isn't called later.
- */
- @SmallTest
- public void testTimedoutNetworkRequest() {
- NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
- NetworkCapabilities.TRANSPORT_WIFI).build();
- final TestNetworkCallback networkCallback = new TestNetworkCallback();
- mCm.requestNetwork(nr, networkCallback, 10);
-
- // pass timeout and validate that UNAVAILABLE is called
- networkCallback.expectCallback(CallbackState.UNAVAILABLE, null);
-
- // create a network satisfying request - validate that request not triggered
- mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
- mWiFiNetworkAgent.connect(false);
- networkCallback.assertNoCallback();
- }
-
- /**
- * Validate that when a network request is unregistered (cancelled) the time-out for that
- * request doesn't trigger the onUnavailable() callback.
- */
- @SmallTest
- public void testTimedoutAfterUnregisteredNetworkRequest() {
- NetworkRequest nr = new NetworkRequest.Builder().addTransportType(
- NetworkCapabilities.TRANSPORT_WIFI).build();
- final TestNetworkCallback networkCallback = new TestNetworkCallback();
- mCm.requestNetwork(nr, networkCallback, 10);
-
- // remove request
- mCm.unregisterNetworkCallback(networkCallback);
-
- // pass timeout and validate that no callbacks
- // Note: doesn't validate that nothing called from CS since even if called the CM already
- // unregisters the callback and won't pass it through!
- try {
- Thread.sleep(15);
- } catch (InterruptedException e) {
- }
- networkCallback.assertNoCallback();
-
- // create a network satisfying request - validate that request not triggered
- mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
- mWiFiNetworkAgent.connect(false);
- networkCallback.assertNoCallback();
- }
-
private static class TestKeepaliveCallback extends PacketKeepaliveCallback {
public static enum CallbackType { ON_STARTED, ON_STOPPED, ON_ERROR };
diff --git a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
index f841bf9..0d5daa5 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkManagementServiceTest.java
@@ -24,7 +24,6 @@
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.LargeTest;
import com.android.server.net.BaseNetworkObserver;
-import com.android.internal.util.test.BroadcastInterceptingContext;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 8d36ac9..541be3d 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -78,7 +78,6 @@
import android.text.format.Time;
import android.util.TrustedTime;
-import com.android.internal.util.test.BroadcastInterceptingContext;
import com.android.server.net.NetworkPolicyManagerService;
import com.google.common.util.concurrent.AbstractFuture;
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
new file mode 100644
index 0000000..0139671
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -0,0 +1,422 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+import android.Manifest.permission;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.net.INetworkScoreCache;
+import android.net.NetworkKey;
+import android.net.NetworkScoreManager;
+import android.net.NetworkScorerAppManager;
+import android.net.NetworkScorerAppManager.NetworkScorerAppData;
+import android.net.ScoredNetwork;
+import android.net.WifiKey;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.provider.Settings.Global;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.MediumTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.internal.R;
+import com.android.server.devicepolicy.MockUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for {@link NetworkScoreService}.
+ */
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class NetworkScoreServiceTest {
+ private static final ScoredNetwork SCORED_NETWORK =
+ new ScoredNetwork(new NetworkKey(new WifiKey("\"ssid\"", "00:00:00:00:00:00")),
+ null /* rssiCurve*/);
+ private static final NetworkScorerAppData PREV_SCORER = new NetworkScorerAppData(
+ "prevPackageName", 0, "prevScorerName", null /* configurationActivityClassName */,
+ "prevScoringServiceClass");
+ private static final NetworkScorerAppData NEW_SCORER = new NetworkScorerAppData(
+ "newPackageName", 1, "newScorerName", null /* configurationActivityClassName */,
+ "newScoringServiceClass");
+
+ @Mock private PackageManager mPackageManager;
+ @Mock private NetworkScorerAppManager mNetworkScorerAppManager;
+ @Mock private Context mContext;
+ @Mock private Resources mResources;
+ @Mock private INetworkScoreCache.Stub mNetworkScoreCache, mNetworkScoreCache2;
+ @Mock private IBinder mIBinder, mIBinder2;
+ @Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor;
+
+ private ContentResolver mContentResolver;
+ private NetworkScoreService mNetworkScoreService;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ when(mNetworkScoreCache.asBinder()).thenReturn(mIBinder);
+ when(mNetworkScoreCache2.asBinder()).thenReturn(mIBinder2);
+ mContentResolver = InstrumentationRegistry.getContext().getContentResolver();
+ when(mContext.getContentResolver()).thenReturn(mContentResolver);
+ when(mContext.getResources()).thenReturn(mResources);
+ mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager);
+ }
+
+ @Test
+ public void testSystemReady_networkScorerProvisioned() throws Exception {
+ Settings.Global.putInt(mContentResolver, Global.NETWORK_SCORING_PROVISIONED, 1);
+
+ mNetworkScoreService.systemReady();
+
+ verify(mNetworkScorerAppManager, never()).setActiveScorer(anyString());
+ }
+
+ @Test
+ public void testSystemReady_networkScorerNotProvisioned_defaultScorer() throws Exception {
+ Settings.Global.putInt(mContentResolver, Global.NETWORK_SCORING_PROVISIONED, 0);
+
+ when(mResources.getString(R.string.config_defaultNetworkScorerPackageName))
+ .thenReturn(NEW_SCORER.mPackageName);
+
+ mNetworkScoreService.systemReady();
+
+ verify(mNetworkScorerAppManager).setActiveScorer(NEW_SCORER.mPackageName);
+ assertEquals(1,
+ Settings.Global.getInt(mContentResolver, Global.NETWORK_SCORING_PROVISIONED));
+
+ }
+
+ @Test
+ public void testSystemReady_networkScorerNotProvisioned_noDefaultScorer() throws Exception {
+ Settings.Global.putInt(mContentResolver, Global.NETWORK_SCORING_PROVISIONED, 0);
+
+ when(mResources.getString(R.string.config_defaultNetworkScorerPackageName))
+ .thenReturn(null);
+
+ mNetworkScoreService.systemReady();
+
+ verify(mNetworkScorerAppManager, never()).setActiveScorer(anyString());
+ assertEquals(1,
+ Settings.Global.getInt(mContentResolver, Global.NETWORK_SCORING_PROVISIONED));
+ }
+
+ @Test
+ public void testSystemRunning() {
+ when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
+
+ mNetworkScoreService.systemRunning();
+
+ verify(mContext).bindServiceAsUser(MockUtils.checkIntent(new Intent().setComponent(
+ new ComponentName(NEW_SCORER.mPackageName, NEW_SCORER.mScoringServiceClassName))),
+ any(ServiceConnection.class),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+ eq(UserHandle.SYSTEM));
+ }
+
+ @Test
+ public void testUpdateScores_notActiveScorer() {
+ when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
+
+ try {
+ mNetworkScoreService.updateScores(new ScoredNetwork[0]);
+ fail("SecurityException expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testUpdateScores_oneRegisteredCache() throws RemoteException {
+ when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
+
+ mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+ mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
+
+ verify(mNetworkScoreCache).updateScores(mScoredNetworkCaptor.capture());
+
+ assertEquals(1, mScoredNetworkCaptor.getValue().size());
+ assertEquals(SCORED_NETWORK, mScoredNetworkCaptor.getValue().get(0));
+ }
+
+ @Test
+ public void testUpdateScores_twoRegisteredCaches() throws RemoteException {
+ when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
+
+ mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+ mNetworkScoreService.registerNetworkScoreCache(
+ NetworkKey.TYPE_WIFI, mNetworkScoreCache2);
+
+ // updateScores should update both caches
+ mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
+
+ verify(mNetworkScoreCache).updateScores(anyListOf(ScoredNetwork.class));
+ verify(mNetworkScoreCache2).updateScores(anyListOf(ScoredNetwork.class));
+
+ mNetworkScoreService.unregisterNetworkScoreCache(
+ NetworkKey.TYPE_WIFI, mNetworkScoreCache2);
+
+ // updateScores should only update the first cache since the 2nd has been unregistered
+ mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
+
+ verify(mNetworkScoreCache, times(2)).updateScores(anyListOf(ScoredNetwork.class));
+
+ mNetworkScoreService.unregisterNetworkScoreCache(
+ NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+ // updateScores should not update any caches since they are both unregistered
+ mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK});
+
+ verifyNoMoreInteractions(mNetworkScoreCache, mNetworkScoreCache2);
+ }
+
+ @Test
+ public void testClearScores_notActiveScorer_noBroadcastNetworkPermission() {
+ when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
+ when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+ try {
+ mNetworkScoreService.clearScores();
+ fail("SecurityException expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testClearScores_activeScorer_noBroadcastNetworkPermission() {
+ when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
+ when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+
+ mNetworkScoreService.clearScores();
+ }
+
+ @Test
+ public void testClearScores_activeScorer() throws RemoteException {
+ when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
+
+ mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+ mNetworkScoreService.clearScores();
+
+ verify(mNetworkScoreCache).clearScores();
+ }
+
+ @Test
+ public void testClearScores_notActiveScorer_hasBroadcastNetworkPermission()
+ throws RemoteException {
+ when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
+ when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
+
+ mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+ mNetworkScoreService.clearScores();
+
+ verify(mNetworkScoreCache).clearScores();
+ }
+
+ @Test
+ public void testSetActiveScorer_noScoreNetworksPermission() {
+ doThrow(new SecurityException()).when(mContext)
+ .enforceCallingOrSelfPermission(eq(permission.SCORE_NETWORKS), anyString());
+
+ try {
+ mNetworkScoreService.setActiveScorer(null);
+ fail("SecurityException expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testSetActiveScorer_failure() throws RemoteException {
+ when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER);
+ when(mNetworkScorerAppManager.setActiveScorer(NEW_SCORER.mPackageName)).thenReturn(false);
+ mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+ boolean success = mNetworkScoreService.setActiveScorer(NEW_SCORER.mPackageName);
+
+ assertFalse(success);
+ verify(mNetworkScoreCache).clearScores();
+ verify(mContext).bindServiceAsUser(MockUtils.checkIntent(new Intent().setComponent(
+ new ComponentName(PREV_SCORER.mPackageName, PREV_SCORER.mScoringServiceClassName))),
+ any(ServiceConnection.class),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+ eq(UserHandle.SYSTEM));
+ }
+
+ @Test
+ public void testSetActiveScorer_success() throws RemoteException {
+ when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER, NEW_SCORER);
+ when(mNetworkScorerAppManager.setActiveScorer(NEW_SCORER.mPackageName)).thenReturn(true);
+ mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+ boolean success = mNetworkScoreService.setActiveScorer(NEW_SCORER.mPackageName);
+
+ assertTrue(success);
+ verify(mNetworkScoreCache).clearScores();
+ verify(mContext).bindServiceAsUser(MockUtils.checkIntent(new Intent().setComponent(
+ new ComponentName(NEW_SCORER.mPackageName, NEW_SCORER.mScoringServiceClassName))),
+ any(ServiceConnection.class),
+ eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE),
+ eq(UserHandle.SYSTEM));
+ verify(mContext, times(2)).sendBroadcastAsUser(
+ MockUtils.checkIntentAction(NetworkScoreManager.ACTION_SCORER_CHANGED),
+ eq(UserHandle.SYSTEM));
+ }
+
+ @Test
+ public void testDisableScoring_notActiveScorer_noBroadcastNetworkPermission() {
+ when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
+ when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+ .thenReturn(PackageManager.PERMISSION_DENIED);
+
+ try {
+ mNetworkScoreService.disableScoring();
+ fail("SecurityException expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+
+ }
+
+ @Test
+ public void testDisableScoring_activeScorer() throws RemoteException {
+ when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(true);
+ when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER, null);
+ when(mNetworkScorerAppManager.setActiveScorer(null)).thenReturn(true);
+ mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+ mNetworkScoreService.disableScoring();
+
+ verify(mNetworkScoreCache).clearScores();
+ verify(mContext).sendBroadcastAsUser(
+ MockUtils.checkIntent(new Intent(NetworkScoreManager.ACTION_SCORER_CHANGED)
+ .setPackage(PREV_SCORER.mPackageName)),
+ eq(UserHandle.SYSTEM));
+ verify(mContext, never()).bindServiceAsUser(any(Intent.class),
+ any(ServiceConnection.class), anyInt(), any(UserHandle.class));
+ }
+
+ @Test
+ public void testDisableScoring_notActiveScorer_hasBroadcastNetworkPermission()
+ throws RemoteException {
+ when(mNetworkScorerAppManager.isCallerActiveScorer(anyInt())).thenReturn(false);
+ when(mContext.checkCallingOrSelfPermission(permission.BROADCAST_NETWORK_PRIVILEGED))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
+ when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(PREV_SCORER, null);
+ when(mNetworkScorerAppManager.setActiveScorer(null)).thenReturn(true);
+ mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+
+ mNetworkScoreService.disableScoring();
+
+ verify(mNetworkScoreCache).clearScores();
+ verify(mContext).sendBroadcastAsUser(
+ MockUtils.checkIntent(new Intent(NetworkScoreManager.ACTION_SCORER_CHANGED)
+ .setPackage(PREV_SCORER.mPackageName)),
+ eq(UserHandle.SYSTEM));
+ verify(mContext, never()).bindServiceAsUser(any(Intent.class),
+ any(ServiceConnection.class), anyInt(), any(UserHandle.class));
+ }
+
+ @Test
+ public void testRegisterNetworkScoreCache_noBroadcastNetworkPermission() {
+ doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+ eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
+
+ try {
+ mNetworkScoreService.registerNetworkScoreCache(
+ NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+ fail("SecurityException expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testUnregisterNetworkScoreCache_noBroadcastNetworkPermission() {
+ doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+ eq(permission.BROADCAST_NETWORK_PRIVILEGED), anyString());
+
+ try {
+ mNetworkScoreService.unregisterNetworkScoreCache(
+ NetworkKey.TYPE_WIFI, mNetworkScoreCache);
+ fail("SecurityException expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testDump_noDumpPermission() {
+ doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission(
+ eq(permission.DUMP), anyString());
+
+ try {
+ mNetworkScoreService.dump(
+ new FileDescriptor(), new PrintWriter(new StringWriter()), new String[0]);
+ fail("SecurityException expected");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ @Test
+ public void testDump_doesNotCrash() {
+ when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER);
+ StringWriter stringWriter = new StringWriter();
+
+ mNetworkScoreService.dump(
+ new FileDescriptor(), new PrintWriter(stringWriter), new String[0]);
+
+ assertFalse(stringWriter.toString().isEmpty());
+ }
+}
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityEventBuilderTest.java
diff --git a/tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java b/services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/IpConnectivityMetricsTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/IpConnectivityMetricsTest.java
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/services/tests/servicestests/src/com/android/server/connectivity/LingerMonitorTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/LingerMonitorTest.java
diff --git a/tests/net/java/com/android/server/connectivity/MetricsLoggerServiceTest.java b/services/tests/servicestests/src/com/android/server/connectivity/MetricsLoggerServiceTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/MetricsLoggerServiceTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/MetricsLoggerServiceTest.java
diff --git a/tests/net/java/com/android/server/connectivity/MetricsTestUtil.java b/services/tests/servicestests/src/com/android/server/connectivity/MetricsTestUtil.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/MetricsTestUtil.java
rename to services/tests/servicestests/src/com/android/server/connectivity/MetricsTestUtil.java
diff --git a/tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java b/services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/NetdEventListenerServiceTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/NetdEventListenerServiceTest.java
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/services/tests/servicestests/src/com/android/server/connectivity/TetheringTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/TetheringTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/TetheringTest.java
diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/services/tests/servicestests/src/com/android/server/connectivity/VpnTest.java
similarity index 100%
rename from tests/net/java/com/android/server/connectivity/VpnTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/VpnTest.java
diff --git a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java b/services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
similarity index 97%
rename from tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
rename to services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
index 9f7261d..a30b362 100644
--- a/tests/net/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
+++ b/services/tests/servicestests/src/com/android/server/connectivity/tethering/TetherInterfaceStateMachineTest.java
@@ -59,14 +59,13 @@
@Mock private INetworkStatsService mStatsService;
@Mock private IControlsTethering mTetherHelper;
@Mock private InterfaceConfiguration mInterfaceConfiguration;
- @Mock private IPv6TetheringInterfaceServices mIPv6TetheringInterfaceServices;
private final TestLooper mLooper = new TestLooper();
private TetherInterfaceStateMachine mTestedSm;
private void initStateMachine(int interfaceType) throws Exception {
mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(), interfaceType,
- mNMService, mStatsService, mTetherHelper, mIPv6TetheringInterfaceServices);
+ mNMService, mStatsService, mTetherHelper);
mTestedSm.start();
// Starting the state machine always puts us in a consistent state and notifies
// the test of the world that we've changed from an unknown to available state.
@@ -92,8 +91,7 @@
@Test
public void startsOutAvailable() {
mTestedSm = new TetherInterfaceStateMachine(IFACE_NAME, mLooper.getLooper(),
- ConnectivityManager.TETHERING_BLUETOOTH, mNMService, mStatsService, mTetherHelper,
- mIPv6TetheringInterfaceServices);
+ ConnectivityManager.TETHERING_BLUETOOTH, mNMService, mStatsService, mTetherHelper);
mTestedSm.start();
mLooper.dispatchAll();
verify(mTetherHelper).notifyInterfaceStateChange(
@@ -276,4 +274,4 @@
upstreamIface);
mLooper.dispatchAll();
}
-}
+}
\ No newline at end of file
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
index 58db192..3806da6 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
@@ -82,6 +82,21 @@
return Mockito.argThat(m);
}
+ public static Intent checkIntent(final Intent intent) {
+ final Matcher<Intent> m = new BaseMatcher<Intent>() {
+ @Override
+ public boolean matches(Object item) {
+ if (item == null) return false;
+ return intent.filterEquals((Intent) item);
+ }
+ @Override
+ public void describeTo(Description description) {
+ description.appendText(intent.toString());
+ }
+ };
+ return Mockito.argThat(m);
+ }
+
public static Bundle checkUserRestrictions(String... keys) {
final Bundle expected = DpmTestUtils.newRestrictions(Preconditions.checkNotNull(keys));
final Matcher<Bundle> m = new BaseMatcher<Bundle>() {
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
index 4b69eb3..94c6711 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkStatsServiceTest.java
@@ -88,7 +88,7 @@
import android.util.TrustedTime;
import com.android.internal.net.VpnInfo;
-import com.android.internal.util.test.BroadcastInterceptingContext;
+import com.android.server.BroadcastInterceptingContext;
import com.android.server.net.NetworkStatsService;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings;
import com.android.server.net.NetworkStatsService.NetworkStatsSettings.Config;
diff --git a/test-runner/Android.mk b/test-runner/Android.mk
index 68bde35..a317994 100644
--- a/test-runner/Android.mk
+++ b/test-runner/Android.mk
@@ -20,7 +20,7 @@
LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_JAVA_LIBRARIES := core-oj core-libart core-junit framework
+LOCAL_JAVA_LIBRARIES := core-oj core-libart junit framework
LOCAL_STATIC_JAVA_LIBRARIES := junit-runner
LOCAL_MODULE:= android.test.runner
diff --git a/tests/net/Android.mk b/tests/net/Android.mk
deleted file mode 100644
index 8aa27a9..0000000
--- a/tests/net/Android.mk
+++ /dev/null
@@ -1,80 +0,0 @@
-#########################################################################
-# Build FrameworksNetTests package
-#########################################################################
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, java)
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- frameworks-base-testutils \
- framework-protos \
- android-support-test \
- mockito-target-minus-junit4 \
- platform-test-annotations \
- services.core \
- services.net
-
-LOCAL_JAVA_LIBRARIES := \
- android.test.runner
-
-LOCAL_PACKAGE_NAME := FrameworksNetTests
-
-LOCAL_CERTIFICATE := platform
-
-# These are not normally accessible from apps so they must be explicitly included.
-LOCAL_JNI_SHARED_LIBRARIES := libframeworksnettestsjni \
- libbacktrace \
- libbase \
- libbinder \
- libc++ \
- libcutils \
- liblog \
- liblzma \
- libnativehelper \
- libnetdaidl \
- libui \
- libunwind \
- libutils
-
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
-
-include $(BUILD_PACKAGE)
-
-#########################################################################
-# Build JNI Shared Library
-#########################################################################
-
-LOCAL_PATH:= $(LOCAL_PATH)/jni
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_CFLAGS := -Wall -Wextra -Werror
-
-LOCAL_C_INCLUDES := \
- libpcap \
- hardware/google/apf
-
-LOCAL_SRC_FILES := $(call all-cpp-files-under)
-
-LOCAL_SHARED_LIBRARIES := \
- libbinder \
- liblog \
- libcutils \
- libnativehelper \
- libnetdaidl
-
-LOCAL_STATIC_LIBRARIES := \
- libpcap \
- libapf
-
-LOCAL_MODULE := libframeworksnettestsjni
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/tests/net/AndroidManifest.xml b/tests/net/AndroidManifest.xml
deleted file mode 100644
index e069dd0..0000000
--- a/tests/net/AndroidManifest.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2016 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.frameworks.tests.net">
-
- <uses-permission android:name="android.permission.READ_LOGS" />
- <uses-permission android:name="android.permission.WRITE_SETTINGS" />
- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.BROADCAST_STICKY" />
- <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
- <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
- <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
- <uses-permission android:name="android.permission.WAKE_LOCK" />
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
- <uses-permission android:name="android.permission.REAL_GET_TASKS" />
- <uses-permission android:name="android.permission.GET_DETAILED_TASKS" />
- <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
- <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
- <uses-permission android:name="android.permission.MODIFY_NETWORK_ACCOUNTING" />
- <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
- <uses-permission android:name="android.permission.MANAGE_USERS" />
- <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
- <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />
- <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
- <uses-permission android:name="android.permission.PACKET_KEEPALIVE_OFFLOAD" />
- <uses-permission android:name="android.permission.GET_INTENT_SENDER_INTENT" />
- <uses-permission android:name="android.permission.MANAGE_ACTIVITY_STACKS" />
- <uses-permission android:name="android.permission.INSTALL_PACKAGES" />
-
- <application>
- <uses-library android:name="android.test.runner" />
- </application>
-
- <instrumentation
- android:name="android.support.test.runner.AndroidJUnitRunner"
- android:targetPackage="com.android.frameworks.tests.net"
- android:label="Frameworks Networking Tests" />
-</manifest>
diff --git a/tests/utils/testutils/Android.mk b/tests/utils/testutils/Android.mk
index acbe4bc..d53167f 100644
--- a/tests/utils/testutils/Android.mk
+++ b/tests/utils/testutils/Android.mk
@@ -27,6 +27,4 @@
android-support-test \
mockito-target
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 69e9fcd..43e6246 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -746,50 +746,6 @@
@SystemApi
public int numAssociation;
- /**
- * @hide
- * Number of time user disabled WiFi while associated to this configuration with Low RSSI.
- */
- public int numUserTriggeredWifiDisableLowRSSI;
-
- /**
- * @hide
- * Number of time user disabled WiFi while associated to this configuration with Bad RSSI.
- */
- public int numUserTriggeredWifiDisableBadRSSI;
-
- /**
- * @hide
- * Number of time user disabled WiFi while associated to this configuration
- * and RSSI was not HIGH.
- */
- public int numUserTriggeredWifiDisableNotHighRSSI;
-
- /**
- * @hide
- * Number of ticks associated to this configuration with Low RSSI.
- */
- public int numTicksAtLowRSSI;
-
- /**
- * @hide
- * Number of ticks associated to this configuration with Bad RSSI.
- */
- public int numTicksAtBadRSSI;
-
- /**
- * @hide
- * Number of ticks associated to this configuration
- * and RSSI was not HIGH.
- */
- public int numTicksAtNotHighRSSI;
- /**
- * @hide
- * Number of time user (WifiManager) triggered association to this configuration.
- * TODO: count this only for Wifi Settings uuid, so as to not count 3rd party apps
- */
- public int numUserTriggeredJoinAttempts;
-
/** @hide
* Boost given to RSSI on a home network for the purpose of calculating the score
* This adds stickiness to home networks, as defined by:
@@ -1630,16 +1586,6 @@
sbuf.append('\n');
}
}
- sbuf.append("triggeredLow: ").append(this.numUserTriggeredWifiDisableLowRSSI);
- sbuf.append(" triggeredBad: ").append(this.numUserTriggeredWifiDisableBadRSSI);
- sbuf.append(" triggeredNotHigh: ").append(this.numUserTriggeredWifiDisableNotHighRSSI);
- sbuf.append('\n');
- sbuf.append("ticksLow: ").append(this.numTicksAtLowRSSI);
- sbuf.append(" ticksBad: ").append(this.numTicksAtBadRSSI);
- sbuf.append(" ticksNotHigh: ").append(this.numTicksAtNotHighRSSI);
- sbuf.append('\n');
- sbuf.append("triggeredJoin: ").append(this.numUserTriggeredJoinAttempts);
- sbuf.append('\n');
return sbuf.toString();
}
@@ -1946,13 +1892,6 @@
numScorerOverride = source.numScorerOverride;
numScorerOverrideAndSwitchedNetwork = source.numScorerOverrideAndSwitchedNetwork;
numAssociation = source.numAssociation;
- numUserTriggeredWifiDisableLowRSSI = source.numUserTriggeredWifiDisableLowRSSI;
- numUserTriggeredWifiDisableBadRSSI = source.numUserTriggeredWifiDisableBadRSSI;
- numUserTriggeredWifiDisableNotHighRSSI = source.numUserTriggeredWifiDisableNotHighRSSI;
- numTicksAtLowRSSI = source.numTicksAtLowRSSI;
- numTicksAtBadRSSI = source.numTicksAtBadRSSI;
- numTicksAtNotHighRSSI = source.numTicksAtNotHighRSSI;
- numUserTriggeredJoinAttempts = source.numUserTriggeredJoinAttempts;
userApproved = source.userApproved;
numNoInternetAccessReports = source.numNoInternetAccessReports;
noInternetAccessExpected = source.noInternetAccessExpected;
@@ -2018,13 +1957,6 @@
dest.writeInt(numScorerOverride);
dest.writeInt(numScorerOverrideAndSwitchedNetwork);
dest.writeInt(numAssociation);
- dest.writeInt(numUserTriggeredWifiDisableLowRSSI);
- dest.writeInt(numUserTriggeredWifiDisableBadRSSI);
- dest.writeInt(numUserTriggeredWifiDisableNotHighRSSI);
- dest.writeInt(numTicksAtLowRSSI);
- dest.writeInt(numTicksAtBadRSSI);
- dest.writeInt(numTicksAtNotHighRSSI);
- dest.writeInt(numUserTriggeredJoinAttempts);
dest.writeInt(userApproved);
dest.writeInt(numNoInternetAccessReports);
dest.writeInt(noInternetAccessExpected ? 1 : 0);
@@ -2090,13 +2022,6 @@
config.numScorerOverride = in.readInt();
config.numScorerOverrideAndSwitchedNetwork = in.readInt();
config.numAssociation = in.readInt();
- config.numUserTriggeredWifiDisableLowRSSI = in.readInt();
- config.numUserTriggeredWifiDisableBadRSSI = in.readInt();
- config.numUserTriggeredWifiDisableNotHighRSSI = in.readInt();
- config.numTicksAtLowRSSI = in.readInt();
- config.numTicksAtBadRSSI = in.readInt();
- config.numTicksAtNotHighRSSI = in.readInt();
- config.numUserTriggeredJoinAttempts = in.readInt();
config.userApproved = in.readInt();
config.numNoInternetAccessReports = in.readInt();
config.noInternetAccessExpected = in.readInt() != 0;
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
new file mode 100644
index 0000000..5f949747
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.os.Parcel;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.WifiConfiguration}.
+ */
+public class WifiConfigurationTest {
+
+ @Before
+ public void setUp() {
+ }
+
+ /**
+ * Check that parcel marshalling/unmarshalling works
+ *
+ * Create and populate a WifiConfiguration.
+ * Marshall and unmashall it, and expect to recover a copy of the original.
+ * Marshall the resulting object, and expect the bytes to match the
+ * first marshall result.
+ */
+ @Test
+ public void testWifiConfigurationParcel() {
+ String cookie = "C O.o |<IE";
+ WifiConfiguration config = new WifiConfiguration();
+ config.setPasspointManagementObjectTree(cookie);
+ Parcel parcelW = Parcel.obtain();
+ config.writeToParcel(parcelW, 0);
+ byte[] bytes = parcelW.marshall();
+ parcelW.recycle();
+
+ Parcel parcelR = Parcel.obtain();
+ parcelR.unmarshall(bytes, 0, bytes.length);
+ parcelR.setDataPosition(0);
+ WifiConfiguration reconfig = WifiConfiguration.CREATOR.createFromParcel(parcelR);
+
+ // lacking a useful config.equals, check one field near the end.
+ assertEquals(cookie, reconfig.getMoTree());
+
+ Parcel parcelWW = Parcel.obtain();
+ reconfig.writeToParcel(parcelWW, 0);
+ byte[] rebytes = parcelWW.marshall();
+ parcelWW.recycle();
+
+ assertArrayEquals(bytes, rebytes);
+ }
+}