summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--service/java/com/android/server/wifi/WifiInjector.java2
-rw-r--r--service/java/com/android/server/wifi/WifiNetworkFactory.java76
-rw-r--r--tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java59
3 files changed, 114 insertions, 23 deletions
diff --git a/service/java/com/android/server/wifi/WifiInjector.java b/service/java/com/android/server/wifi/WifiInjector.java
index 35fd64c5e..646b7a014 100644
--- a/service/java/com/android/server/wifi/WifiInjector.java
+++ b/service/java/com/android/server/wifi/WifiInjector.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AppOpsManager;
+import android.companion.CompanionDeviceManager;
import android.content.Context;
import android.net.IpMemoryStore;
import android.net.NetworkCapabilities;
@@ -624,6 +625,7 @@ public class WifiInjector {
(ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE),
(AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE),
(AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE),
+ mContext.getSystemService(CompanionDeviceManager.class),
mClock, this, wifiConnectivityManager, mWifiConfigManager,
mWifiConfigStore, mWifiPermissionsUtil, mWifiMetrics);
}
diff --git a/service/java/com/android/server/wifi/WifiNetworkFactory.java b/service/java/com/android/server/wifi/WifiNetworkFactory.java
index 8d3072fe8..8bb87c65c 100644
--- a/service/java/com/android/server/wifi/WifiNetworkFactory.java
+++ b/service/java/com/android/server/wifi/WifiNetworkFactory.java
@@ -24,6 +24,7 @@ import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AppOpsManager;
+import android.companion.CompanionDeviceManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -55,6 +56,7 @@ import android.util.Log;
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.server.wifi.proto.nano.WifiMetricsProto;
import com.android.server.wifi.util.ExternalCallbackTracker;
import com.android.server.wifi.util.ScanResultUtil;
@@ -107,6 +109,7 @@ public class WifiNetworkFactory extends NetworkFactory {
private final ActivityManager mActivityManager;
private final AlarmManager mAlarmManager;
private final AppOpsManager mAppOpsManager;
+ private final CompanionDeviceManager mCompanionDeviceManager;
private final Clock mClock;
private final Handler mHandler;
private final WifiInjector mWifiInjector;
@@ -343,6 +346,7 @@ public class WifiNetworkFactory extends NetworkFactory {
public WifiNetworkFactory(Looper looper, Context context, NetworkCapabilities nc,
ActivityManager activityManager, AlarmManager alarmManager,
AppOpsManager appOpsManager,
+ CompanionDeviceManager companionDeviceManager,
Clock clock, WifiInjector wifiInjector,
WifiConnectivityManager connectivityManager,
WifiConfigManager configManager,
@@ -354,6 +358,7 @@ public class WifiNetworkFactory extends NetworkFactory {
mActivityManager = activityManager;
mAlarmManager = alarmManager;
mAppOpsManager = appOpsManager;
+ mCompanionDeviceManager = companionDeviceManager;
mClock = clock;
mHandler = new Handler(looper);
mWifiInjector = wifiInjector;
@@ -1245,30 +1250,61 @@ public class WifiNetworkFactory extends NetworkFactory {
return selectedScanResult.BSSID;
}
+ private boolean isAccessPointApprovedInInternalApprovalList(
+ @NonNull ScanResult scanResult, @NonNull String requestorPackageName) {
+ Set<AccessPoint> approvedAccessPoints =
+ mUserApprovedAccessPointMap.get(requestorPackageName);
+ if (approvedAccessPoints == null) return false;
+ ScanResultMatchInfo fromScanResult = ScanResultMatchInfo.fromScanResult(scanResult);
+ AccessPoint accessPoint =
+ new AccessPoint(scanResult.SSID,
+ MacAddress.fromString(scanResult.BSSID), fromScanResult.networkType);
+ if (!approvedAccessPoints.contains(accessPoint)) return false;
+ // keep the most recently used AP in the end
+ approvedAccessPoints.remove(accessPoint);
+ approvedAccessPoints.add(accessPoint);
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Found " + scanResult
+ + " in internal user approved access point for " + requestorPackageName);
+ }
+ return true;
+ }
+
+ private boolean isAccessPointApprovedInCompanionDeviceManager(
+ @NonNull ScanResult scanResult, @NonNull UserHandle requestorUserHandle,
+ @NonNull String requestorPackageName) {
+ boolean approved = mCompanionDeviceManager.isDeviceAssociated(
+ requestorPackageName, MacAddress.fromString(scanResult.BSSID), requestorUserHandle);
+ if (!approved) return false;
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "Found " + scanResult
+ + " in CDM user approved access point for " + requestorPackageName);
+ }
+ return true;
+ }
+
private @Nullable ScanResult
findUserApprovedAccessPointForActiveRequestFromActiveMatchedScanResults() {
if (mActiveSpecificNetworkRequestSpecifier == null
- || mActiveMatchedScanResults == null) return null;
- String requestorPackageName = mActiveSpecificNetworkRequestSpecifier.requestorPackageName;
- Set<AccessPoint> approvedAccessPoints =
- mUserApprovedAccessPointMap.get(requestorPackageName);
- if (approvedAccessPoints == null) return null;
- for (ScanResult scanResult : mActiveMatchedScanResults) {
- ScanResultMatchInfo fromScanResult = ScanResultMatchInfo.fromScanResult(scanResult);
- AccessPoint accessPoint =
- new AccessPoint(scanResult.SSID,
- MacAddress.fromString(scanResult.BSSID), fromScanResult.networkType);
- if (approvedAccessPoints.contains(accessPoint)) {
- // keep the most recently used AP in the end
- approvedAccessPoints.remove(accessPoint);
- approvedAccessPoints.add(accessPoint);
- if (mVerboseLoggingEnabled) {
- Log.v(TAG, "Found " + accessPoint
- + " in user approved access point for " + requestorPackageName);
- }
- return scanResult;
- }
+ || ArrayUtils.size(mActiveMatchedScanResults) != 1) {
+ return null;
}
+ // There should only 1 matched scan result since the request contains a specific
+ // SSID + BSSID mentioned.
+ ScanResult scanResult = mActiveMatchedScanResults.get(0);
+ String requestorPackageName = mActiveSpecificNetworkRequestSpecifier.requestorPackageName;
+ UserHandle requestorUserHandle =
+ UserHandle.getUserHandleForUid(mActiveSpecificNetworkRequestSpecifier.requestorUid);
+ // Check if access point is approved via CDM first.
+ if (isAccessPointApprovedInCompanionDeviceManager(
+ scanResult, requestorUserHandle, requestorPackageName)) {
+ return scanResult;
+ }
+ // Check if access point is approved in internal approval list next.
+ if (isAccessPointApprovedInInternalApprovalList(scanResult, requestorPackageName)) {
+ return scanResult;
+ }
+ // no bypass approvals, show UI.
return null;
}
diff --git a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
index f7cd39c43..b2f74f68f 100644
--- a/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
+++ b/tests/wifitests/src/com/android/server/wifi/WifiNetworkFactoryTest.java
@@ -32,6 +32,7 @@ import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.AlarmManager.OnAlarmListener;
import android.app.AppOpsManager;
+import android.companion.CompanionDeviceManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -124,6 +125,7 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
@Mock ActivityManager mActivityManager;
@Mock AlarmManager mAlarmManager;
@Mock AppOpsManager mAppOpsManager;
+ @Mock CompanionDeviceManager mCompanionDeviceManager;
@Mock Clock mClock;
@Mock WifiInjector mWifiInjector;
@Mock WifiConnectivityManager mWifiConnectivityManager;
@@ -194,9 +196,9 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
when(mWifiScanner.getSingleScanResults()).thenReturn(Collections.emptyList());
mWifiNetworkFactory = new WifiNetworkFactory(mLooper.getLooper(), mContext,
- mNetworkCapabilities, mActivityManager, mAlarmManager, mAppOpsManager, mClock,
- mWifiInjector, mWifiConnectivityManager, mWifiConfigManager, mWifiConfigStore,
- mWifiPermissionsUtil, mWifiMetrics);
+ mNetworkCapabilities, mActivityManager, mAlarmManager, mAppOpsManager,
+ mCompanionDeviceManager, mClock, mWifiInjector, mWifiConnectivityManager,
+ mWifiConfigManager, mWifiConfigStore, mWifiPermissionsUtil, mWifiMetrics);
ArgumentCaptor<NetworkRequestStoreData.DataSource> dataSourceArgumentCaptor =
ArgumentCaptor.forClass(NetworkRequestStoreData.DataSource.class);
@@ -2470,6 +2472,57 @@ public class WifiNetworkFactoryTest extends WifiBaseTest {
/**
* Verify the user approval bypass for a specific request for an access point that was already
+ * approved previously via CDM and the scan result is present in the cached scan results.
+ */
+ @Test
+ public void
+ testNetworkSpecifierMatchSuccessUsingLiteralSsidAndBssidMatchApprovedViaCDMWithCache()
+ throws Exception {
+ // Setup scan data for WPA-PSK networks.
+ setupScanData(SCAN_RESULT_TYPE_WPA_PSK,
+ TEST_SSID_1, TEST_SSID_2, TEST_SSID_3, TEST_SSID_4);
+
+ // Choose the matching scan result.
+ ScanResult matchingScanResult = mTestScanDatas[0].getResults()[0];
+
+ // Setup CDM approval for the scan result.
+ when(mCompanionDeviceManager.isDeviceAssociated(
+ TEST_PACKAGE_NAME_1,
+ MacAddress.fromString(matchingScanResult.BSSID),
+ UserHandle.getUserHandleForUid(TEST_UID_1))).thenReturn(true);
+
+ // simulate no cache expiry
+ when(mClock.getElapsedSinceBootMillis()).thenReturn(0L);
+ // Simulate the cached results matching.
+ when(mWifiScanner.getSingleScanResults())
+ .thenReturn(Arrays.asList(mTestScanDatas[0].getResults()));
+
+ PatternMatcher ssidPatternMatch =
+ new PatternMatcher(TEST_SSID_1, PatternMatcher.PATTERN_LITERAL);
+ Pair<MacAddress, MacAddress> bssidPatternMatch =
+ Pair.create(MacAddress.fromString(matchingScanResult.BSSID),
+ MacAddress.BROADCAST_ADDRESS);
+ WifiNetworkSpecifier specifier = new WifiNetworkSpecifier(
+ ssidPatternMatch, bssidPatternMatch,
+ WifiConfigurationTestUtil.createPskNetwork(), TEST_UID_1, TEST_PACKAGE_NAME_1);
+ mNetworkRequest.networkCapabilities.setNetworkSpecifier(specifier);
+ mWifiNetworkFactory.needNetworkFor(mNetworkRequest, 0);
+
+ // Verify we did not trigger the UI for the second request.
+ verify(mContext, never()).startActivityAsUser(any(), any());
+ // Verify we did not trigger a scan.
+ verify(mWifiScanner, never()).startScan(any(), any(), any());
+ // Verify we did not trigger the match callback.
+ verify(mNetworkRequestMatchCallback, never()).onMatch(anyList());
+ // Verify that we sent a connection attempt to ClientModeImpl
+ verify(mClientModeImpl).connect(eq(null), anyInt(),
+ any(Binder.class), mConnectListenerArgumentCaptor.capture(), anyInt(), anyInt());
+
+ verify(mWifiMetrics).incrementNetworkRequestApiNumUserApprovalBypass();
+ }
+
+ /**
+ * Verify the user approval bypass for a specific request for an access point that was already
* approved previously and the scan result is present in the cached scan results, but the
* results are stale.
*/