Add DO API to get wifi mac address
Bug 25496044
Change-Id: Ib1f0ce4ca10951edcfaa0aa79ae5c2d142a74599
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index b3b647f..5c3a55d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -71,6 +71,8 @@
import android.net.ConnectivityManager;
import android.net.ProxyInfo;
import android.net.Uri;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Bundle;
@@ -1121,6 +1123,10 @@
return Looper.myLooper();
}
+ WifiManager getWifiManager() {
+ return mContext.getSystemService(WifiManager.class);
+ }
+
long binderClearCallingIdentity() {
return Binder.clearCallingIdentity();
}
@@ -6871,6 +6877,25 @@
return true;
}
+ @Override
+ public String getWifiMacAddress() {
+ // Make sure caller has DO.
+ synchronized (this) {
+ getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
+ }
+
+ final long ident = mInjector.binderClearCallingIdentity();
+ try {
+ final WifiInfo wifiInfo = mInjector.getWifiManager().getConnectionInfo();
+ if (wifiInfo == null) {
+ return null;
+ }
+ return wifiInfo.hasRealMacAddress() ? wifiInfo.getMacAddress() : null;
+ } finally {
+ mInjector.binderRestoreCallingIdentity(ident);
+ }
+ }
+
/**
* Returns the target sdk version number that the given packageName was built for
* in the given user.
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 79ba08d..0159356 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -26,10 +26,12 @@
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.pm.PackageManager;
+import android.net.wifi.WifiInfo;
import android.os.Bundle;
import android.os.Process;
import android.os.UserHandle;
import android.os.UserManager;
+import android.test.MoreAsserts;
import android.util.Pair;
import org.mockito.ArgumentCaptor;
@@ -1175,4 +1177,64 @@
// TODO Make sure restrictions are written to the file.
}
+
+ public void testGetMacAddress() throws Exception {
+ mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
+ mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+ mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
+
+ // In this test, change the caller user to "system".
+ mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
+
+ // Make sure admin1 is installed on system user.
+ setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
+
+ // Test 1. Caller doesn't have DO or DA.
+ try {
+ dpm.getWifiMacAddress();
+ fail();
+ } catch (SecurityException e) {
+ MoreAsserts.assertContainsRegex("No active admin owned", e.getMessage());
+ }
+
+ // DO needs to be an DA.
+ dpm.setActiveAdmin(admin1, /* replace =*/ false);
+ assertTrue(dpm.isAdminActive(admin1));
+
+ // Test 2. Caller has DA, but not DO.
+ try {
+ dpm.getWifiMacAddress();
+ fail();
+ } catch (SecurityException e) {
+ MoreAsserts.assertContainsRegex("No active admin owned", e.getMessage());
+ }
+
+ // Test 3. Caller has PO, but not DO.
+ assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
+ try {
+ dpm.getWifiMacAddress();
+ fail();
+ } catch (SecurityException e) {
+ MoreAsserts.assertContainsRegex("No active admin owned", e.getMessage());
+ }
+
+ // Remove PO.
+ dpm.clearProfileOwner(admin1);
+
+ // Test 4, Caller is DO now.
+ assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
+
+ // 4-1. But no WifiInfo.
+ assertNull(dpm.getWifiMacAddress());
+
+ // 4-2. Returns WifiInfo, but with the default MAC.
+ when(mContext.wifiManager.getConnectionInfo()).thenReturn(new WifiInfo());
+ assertNull(dpm.getWifiMacAddress());
+
+ // 4-3. With a real MAC address.
+ final WifiInfo wi = new WifiInfo();
+ wi.setMacAddress("11:22:33:44:55:66");
+ when(mContext.wifiManager.getConnectionInfo()).thenReturn(wi);
+ assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress());
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
index bb1e06d..66d701d 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java
@@ -31,6 +31,7 @@
import android.content.pm.PackageManagerInternal;
import android.content.pm.UserInfo;
import android.media.IAudioService;
+import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager.WakeLock;
@@ -217,6 +218,7 @@
public final IBackupManager ibackupManager;
public final IAudioService iaudioService;
public final LockPatternUtils lockPatternUtils;
+ public final WifiManager wifiManager;
public final SettingsForMock settings;
public final MockContentResolver contentResolver;
@@ -249,6 +251,7 @@
ibackupManager = mock(IBackupManager.class);
iaudioService = mock(IAudioService.class);
lockPatternUtils = mock(LockPatternUtils.class);
+ wifiManager = mock(WifiManager.class);
settings = mock(SettingsForMock.class);
// Package manager is huge, so we use a partial mock instead.
@@ -303,6 +306,8 @@
return userManager;
case Context.POWER_SERVICE:
return powerManager;
+ case Context.WIFI_SERVICE:
+ return wifiManager;
}
throw new UnsupportedOperationException();
}