summaryrefslogtreecommitdiff
path: root/service
diff options
context:
space:
mode:
authorRoshan Pius <rpius@google.com>2018-09-24 13:04:47 -0700
committerRoshan Pius <rpius@google.com>2018-10-31 09:22:35 -0700
commit0c4c806bcd0990fce252a6c6f0a413faf8e197f3 (patch)
tree6cb5f63897a2726479f58786af82ec268b12c700 /service
parentd461ed97902a08f6f2a7014cbeafb288b590539e (diff)
WifiNetworkFactory: Implement |acceptRequest|
The wifi network factory will accept network requests for the following cases: a) Request is for a generic wifi network (legacy mechanism). b) Specific Request from a foreground app. c) Specific Request from a foreground service when we're not already processing another specific request from a foreground app. Also, modified the |needNetworkFor| & |releaseNetworkFor| to store & clear the active network request. Further processing in these methods will be added in further CL. Also, added MatchAllNetworkSpecifier in the capabilities used by WifiNetworkFactory. Bug: 113878056 Test: Unit tests Change-Id: I69a206cffe4e8b6387d2df71526142f89b95c767
Diffstat (limited to 'service')
-rw-r--r--service/java/com/android/server/wifi/ClientModeImpl.java9
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java4
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkFactory.java150
3 files changed, 146 insertions, 17 deletions
diff --git a/service/java/com/android/server/wifi/ClientModeImpl.java b/service/java/com/android/server/wifi/ClientModeImpl.java
index d79d37806..ce71f36db 100644
--- a/service/java/com/android/server/wifi/ClientModeImpl.java
+++ b/service/java/com/android/server/wifi/ClientModeImpl.java
@@ -38,6 +38,7 @@ import android.net.IpConfiguration;
import android.net.KeepalivePacketData;
import android.net.LinkProperties;
import android.net.MacAddress;
+import android.net.MatchAllNetworkSpecifier;
import android.net.Network;
import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
@@ -807,15 +808,18 @@ public class ClientModeImpl extends StateMachine {
// TODO - needs to be a bit more dynamic
mDfltNetworkCapabilities = new NetworkCapabilities(mNetworkCapabilitiesFilter);
+ NetworkCapabilities factoryNetworkCapabilities =
+ new NetworkCapabilities(mNetworkCapabilitiesFilter);
+ factoryNetworkCapabilities.setNetworkSpecifier(new MatchAllNetworkSpecifier());
// Make the network factories.
mNetworkFactory = mWifiInjector.makeWifiNetworkFactory(
- mNetworkCapabilitiesFilter, mWifiConnectivityManager);
+ factoryNetworkCapabilities, mWifiConnectivityManager);
// We can't filter untrusted network in the capabilities filter because a trusted
// network would still satisfy a request that accepts untrusted ones.
// We need a second network factory for untrusted network requests because we need a
// different score filter for these requests.
mUntrustedNetworkFactory = mWifiInjector.makeUntrustedWifiNetworkFactory(
- mNetworkCapabilitiesFilter, mWifiConnectivityManager);
+ factoryNetworkCapabilities, mWifiConnectivityManager);
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_ON);
@@ -1077,6 +1081,7 @@ public class ClientModeImpl extends StateMachine {
mWifiConfigManager.enableVerboseLogging(verbose);
mSupplicantStateTracker.enableVerboseLogging(verbose);
mPasspointManager.enableVerboseLogging(verbose);
+ mNetworkFactory.enableVerboseLogging(verbose);
}
private static final String SYSTEM_PROPERTY_LOG_CONTROL_WIFIHAL = "log.tag.WifiHAL";
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 9c2bf2c80..2da06fd4b 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -546,7 +546,9 @@ public class WifiInjector {
public WifiNetworkFactory makeWifiNetworkFactory(
NetworkCapabilities nc, WifiConnectivityManager wifiConnectivityManager) {
return new WifiNetworkFactory(
- mWifiCoreHandlerThread.getLooper(), mContext, nc, wifiConnectivityManager);
+ mWifiCoreHandlerThread.getLooper(), mContext, nc,
+ (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE),
+ wifiConnectivityManager);
}
/**
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index 489601d0d..830ca6557 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -16,10 +16,13 @@
package com.android.server.wifi;
+import android.app.ActivityManager;
import android.content.Context;
import android.net.NetworkCapabilities;
import android.net.NetworkFactory;
import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
+import android.net.wifi.WifiNetworkSpecifier;
import android.os.Looper;
import android.util.Log;
@@ -32,47 +35,166 @@ import java.io.PrintWriter;
public class WifiNetworkFactory extends NetworkFactory {
private static final String TAG = "WifiNetworkFactory";
private static final int SCORE_FILTER = 60;
-
private final WifiConnectivityManager mWifiConnectivityManager;
- private int mConnectionReqCount = 0;
+ private final Context mContext;
+ private final ActivityManager mActivityManager;
+
+ private int mGenericConnectionReqCount = 0;
+ NetworkRequest mActiveSpecificNetworkRequest;
+ // Verbose logging flag.
+ private boolean mVerboseLoggingEnabled = false;
- public WifiNetworkFactory(Looper l, Context c, NetworkCapabilities f,
+ public WifiNetworkFactory(Looper looper, Context context, NetworkCapabilities nc,
+ ActivityManager activityManager,
WifiConnectivityManager connectivityManager) {
- super(l, c, TAG, f);
+ super(looper, context, TAG, nc);
+ mContext = context;
+ mActivityManager = activityManager;
mWifiConnectivityManager = connectivityManager;
setScoreFilter(SCORE_FILTER);
}
+ /**
+ * Enable verbose logging.
+ */
+ public void enableVerboseLogging(int verbose) {
+ mVerboseLoggingEnabled = (verbose > 0);
+ }
+
+ @Override
+ public boolean acceptRequest(NetworkRequest networkRequest, int score) {
+ NetworkSpecifier ns = networkRequest.networkCapabilities.getNetworkSpecifier();
+ // Generic wifi request. Always accept.
+ if (ns == null) {
+ // Generic wifi request. Always accept.
+ } else {
+ // Invalid network specifier.
+ if (!(ns instanceof WifiNetworkSpecifier)) {
+ Log.e(TAG, "Invalid network specifier mentioned. Rejecting");
+ return false;
+ }
+
+ WifiNetworkSpecifier wns = (WifiNetworkSpecifier) ns;
+ // Only allow specific wifi network request from foreground app/service.
+ if (!isRequestFromForegroundAppOrService(wns.requestorUid)) {
+ Log.e(TAG, "Request not from foreground app or service."
+ + " Rejecting request from " + wns.requestorUid);
+ return false;
+ }
+ // If there is a pending request, only proceed if the new request is from a foreground
+ // app.
+ if (mActiveSpecificNetworkRequest != null
+ && !isRequestFromForegroundApp(wns.requestorUid)) {
+ WifiNetworkSpecifier aWns =
+ (WifiNetworkSpecifier) mActiveSpecificNetworkRequest
+ .networkCapabilities
+ .getNetworkSpecifier();
+ if (isRequestFromForegroundApp(aWns.requestorUid)) {
+ Log.e(TAG, "Already processing active request from a foreground app "
+ + aWns.requestorUid + ". Rejecting request from " + wns.requestorUid);
+ return false;
+ }
+ }
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Accepted network request with specifier from fg "
+ + (isRequestFromForegroundApp(wns.requestorUid) ? "app" : "service"));
+ }
+ }
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Accepted network request " + networkRequest);
+ }
+ return true;
+ }
+
@Override
protected void needNetworkFor(NetworkRequest networkRequest, int score) {
- if (++mConnectionReqCount == 1) {
- mWifiConnectivityManager.setTrustedConnectionAllowed(true);
+ NetworkSpecifier ns = networkRequest.networkCapabilities.getNetworkSpecifier();
+ if (ns == null) {
+ // Generic wifi request. Turn on auto-join if necessary.
+ if (++mGenericConnectionReqCount == 1) {
+ mWifiConnectivityManager.setTrustedConnectionAllowed(true);
+ }
+ } else {
+ // Invalid network specifier.
+ if (!(ns instanceof WifiNetworkSpecifier)) {
+ Log.e(TAG, "Invalid network specifier mentioned. Rejecting");
+ return;
+ }
+ // Store the active network request.
+ mActiveSpecificNetworkRequest = new NetworkRequest(networkRequest);
+ // TODO (b/113878056): Complete handling.
}
}
@Override
protected void releaseNetworkFor(NetworkRequest networkRequest) {
- if (mConnectionReqCount == 0) {
- Log.e(TAG, "No valid network request to release");
- return;
- }
- if (--mConnectionReqCount == 0) {
- mWifiConnectivityManager.setTrustedConnectionAllowed(false);
+ NetworkSpecifier ns = networkRequest.networkCapabilities.getNetworkSpecifier();
+ if (ns == null) {
+ // Generic wifi request. Turn off auto-join if necessary.
+ if (mGenericConnectionReqCount == 0) {
+ Log.e(TAG, "No valid network request to release");
+ return;
+ }
+ if (--mGenericConnectionReqCount == 0) {
+ mWifiConnectivityManager.setTrustedConnectionAllowed(false);
+ }
+ } else {
+ // Invalid network specifier.
+ if (!(ns instanceof WifiNetworkSpecifier)) {
+ Log.e(TAG, "Invalid network specifier mentioned. Ingoring");
+ return;
+ }
+ if (!mActiveSpecificNetworkRequest.equals(networkRequest)) {
+ Log.e(TAG, "Network specifier does not match the active request. Ignoring");
+ return;
+ }
+ // Release the active network request.
+ mActiveSpecificNetworkRequest = null;
+ // TODO (b/113878056): Complete handling.
}
}
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
super.dump(fd, pw, args);
- pw.println(TAG + ": mConnectionReqCount " + mConnectionReqCount);
+ pw.println(TAG + ": mGenericConnectionReqCount " + mGenericConnectionReqCount);
+ pw.println(TAG + ": mActiveSpecificNetworkRequest " + mActiveSpecificNetworkRequest);
}
/**
* Check if there is at-least one connection request.
*/
public boolean hasConnectionRequests() {
- return mConnectionReqCount > 0;
+ return mGenericConnectionReqCount > 0 || mActiveSpecificNetworkRequest != null;
+ }
+
+ /**
+ * Check if the request comes from foreground app/service.
+ */
+ private boolean isRequestFromForegroundAppOrService(int requestorUid) {
+ try {
+ String requestorPackageName = mContext.getPackageManager().getNameForUid(requestorUid);
+ return mActivityManager.getPackageImportance(requestorPackageName)
+ <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
+ } catch (SecurityException e) {
+ Log.e(TAG, "Failed to check the app state", e);
+ return false;
+ }
+ }
+
+ /**
+ * Check if the request comes from foreground app.
+ */
+ private boolean isRequestFromForegroundApp(int requestorUid) {
+ try {
+ String requestorPackageName = mContext.getPackageManager().getNameForUid(requestorUid);
+ return mActivityManager.getPackageImportance(requestorPackageName)
+ <= ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+ } catch (SecurityException e) {
+ Log.e(TAG, "Failed to check the app state", e);
+ return false;
+ }
}
}