Add DO API to get wifi mac address

Bug 25496044

Change-Id: Ib1f0ce4ca10951edcfaa0aa79ae5c2d142a74599
This commit is contained in:
Makoto Onuki
2015-11-23 17:15:21 -08:00
parent d79a245ac2
commit a31ebbc439
8 changed files with 121 additions and 0 deletions

View File

@@ -5776,6 +5776,7 @@ package android.app.admin {
method public android.app.admin.SystemUpdatePolicy getSystemUpdatePolicy();
method public java.util.List<android.os.PersistableBundle> getTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName);
method public android.os.Bundle getUserRestrictions(android.content.ComponentName);
method public java.lang.String getWifiMacAddress();
method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
method public boolean hasGrantedPolicy(android.content.ComponentName, int);
method public boolean installCaCert(android.content.ComponentName, byte[]);

View File

@@ -5906,6 +5906,7 @@ package android.app.admin {
method public android.app.admin.SystemUpdatePolicy getSystemUpdatePolicy();
method public java.util.List<android.os.PersistableBundle> getTrustAgentConfiguration(android.content.ComponentName, android.content.ComponentName);
method public android.os.Bundle getUserRestrictions(android.content.ComponentName);
method public java.lang.String getWifiMacAddress();
method public boolean hasCaCertInstalled(android.content.ComponentName, byte[]);
method public boolean hasGrantedPolicy(android.content.ComponentName, int);
method public boolean installCaCert(android.content.ComponentName, byte[]);

View File

@@ -4649,4 +4649,21 @@ public class DevicePolicyManager {
return false;
}
}
/**
* Called by device owner to get the MAC address of the Wi-Fi device.
*
* @return the MAC address of the Wi-Fi device, or null when the information is not
* available. (For example, Wi-Fi hasn't been enabled, or the device doesn't support Wi-Fi.)
*
* <p>The address will be in the {@code XX:XX:XX:XX:XX:XX} format.
*/
public String getWifiMacAddress() {
try {
return mService.getWifiMacAddress();
} catch (RemoteException re) {
Log.w(TAG, "Failed talking with device policy service", re);
return null;
}
}
}

View File

@@ -236,4 +236,5 @@ interface IDevicePolicyManager {
List<String> getKeepUninstalledPackages(in ComponentName admin);
boolean isManagedProfile(in ComponentName admin);
boolean isSystemOnlyUser(in ComponentName admin);
String getWifiMacAddress();
}

View File

@@ -71,6 +71,8 @@ import android.media.IAudioService;
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 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return Looper.myLooper();
}
WifiManager getWifiManager() {
return mContext.getSystemService(WifiManager.class);
}
long binderClearCallingIdentity() {
return Binder.clearCallingIdentity();
}
@@ -6871,6 +6877,25 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
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.

View File

@@ -26,10 +26,12 @@ import android.app.admin.DevicePolicyManagerInternal;
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 @@ public class DevicePolicyManagerTest extends DpmTestBase {
// 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());
}
}

View File

@@ -31,6 +31,7 @@ import android.content.pm.PackageManager;
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 class DpmMockContext extends MockContext {
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 @@ public class DpmMockContext extends MockContext {
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 @@ public class DpmMockContext extends MockContext {
return userManager;
case Context.POWER_SERVICE:
return powerManager;
case Context.WIFI_SERVICE:
return wifiManager;
}
throw new UnsupportedOperationException();
}

View File

@@ -424,6 +424,15 @@ public class WifiInfo implements Parcelable {
return mMacAddress;
}
/**
* @return true if {@link #getMacAddress()} has a real MAC address.
*
* @hide
*/
public boolean hasRealMacAddress() {
return mMacAddress != null && !DEFAULT_MAC_ADDRESS.equals(mMacAddress);
}
/** {@hide} */
public void setMeteredHint(boolean meteredHint) {
mMeteredHint = meteredHint;