import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
private DeviceOwner mDeviceOwner;
+ /**
+ * Whether or not device admin feature is supported. If it isn't return defaults for all
+ * public methods.
+ */
+ private boolean mHasFeature;
+
public static class DevicePolicyData {
int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
int mActivePasswordLength = 0;
*/
public DevicePolicyManagerService(Context context) {
mContext = context;
+ mHasFeature = context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_DEVICE_ADMIN);
mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE))
.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM");
+ if (!mHasFeature) {
+ // Skip the rest of the initialization
+ return;
+ }
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_BOOT_COMPLETED);
filter.addAction(ACTION_EXPIRED_PASSWORD_NOTIFICATION);
}
public DeviceAdminInfo findAdmin(ComponentName adminName, int userHandle) {
+ if (!mHasFeature) {
+ return null;
+ }
enforceCrossUserPermission(userHandle);
Intent resolveIntent = new Intent();
resolveIntent.setComponent(adminName);
}
public void systemReady() {
+ if (!mHasFeature) {
+ return;
+ }
synchronized (this) {
loadSettingsLocked(getUserData(UserHandle.USER_OWNER), UserHandle.USER_OWNER);
loadDeviceOwner();
* @param refreshing true = update an active admin, no error
*/
public void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
enforceCrossUserPermission(userHandle);
}
public boolean isAdminActive(ComponentName adminReceiver, int userHandle) {
+ if (!mHasFeature) {
+ return false;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
return getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null;
}
public boolean hasGrantedPolicy(ComponentName adminReceiver, int policyId, int userHandle) {
+ if (!mHasFeature) {
+ return false;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
ActiveAdmin administrator = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
}
}
+ @SuppressWarnings("unchecked")
public List<ComponentName> getActiveAdmins(int userHandle) {
+ if (!mHasFeature) {
+ return Collections.EMPTY_LIST;
+ }
+
enforceCrossUserPermission(userHandle);
synchronized (this) {
DevicePolicyData policy = getUserData(userHandle);
}
public boolean packageHasActiveAdmins(String packageName, int userHandle) {
+ if (!mHasFeature) {
+ return false;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
DevicePolicyData policy = getUserData(userHandle);
}
public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
}
public void setPasswordQuality(ComponentName who, int quality, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
validateQualityConstant(quality);
enforceCrossUserPermission(userHandle);
}
public int getPasswordQuality(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
}
public void setPasswordMinimumLength(ComponentName who, int length, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
}
public int getPasswordMinimumLength(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
DevicePolicyData policy = getUserData(userHandle);
}
public void setPasswordHistoryLength(ComponentName who, int length, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
}
public int getPasswordHistoryLength(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
DevicePolicyData policy = getUserData(userHandle);
}
public void setPasswordExpirationTimeout(ComponentName who, long timeout, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
* Returns 0 if not configured.
*/
public long getPasswordExpirationTimeout(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0L;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who != null) {
}
public long getPasswordExpiration(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0L;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
return getPasswordExpirationLocked(who, userHandle);
}
public void setPasswordMinimumUpperCase(ComponentName who, int length, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
}
public int getPasswordMinimumUpperCase(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
int length = 0;
}
public int getPasswordMinimumLowerCase(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
int length = 0;
}
public void setPasswordMinimumLetters(ComponentName who, int length, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
}
public int getPasswordMinimumLetters(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
int length = 0;
}
public void setPasswordMinimumNumeric(ComponentName who, int length, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
}
public int getPasswordMinimumNumeric(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
int length = 0;
}
public void setPasswordMinimumSymbols(ComponentName who, int length, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
}
public int getPasswordMinimumSymbols(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
int length = 0;
}
public void setPasswordMinimumNonLetter(ComponentName who, int length, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
}
public int getPasswordMinimumNonLetter(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
int length = 0;
}
public boolean isActivePasswordSufficient(int userHandle) {
+ if (!mHasFeature) {
+ return true;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
DevicePolicyData policy = getUserData(userHandle);
}
public void setMaximumFailedPasswordsForWipe(ComponentName who, int num, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
// This API can only be called by an active device admin,
}
public int getMaximumFailedPasswordsForWipe(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
DevicePolicyData policy = getUserData(userHandle);
}
public boolean resetPassword(String password, int flags, int userHandle) {
+ if (!mHasFeature) {
+ return false;
+ }
enforceCrossUserPermission(userHandle);
int quality;
synchronized (this) {
}
public void setMaximumTimeToLock(ComponentName who, long timeMs, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
}
public long getMaximumTimeToLock(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
long time = 0;
}
public void lockNow() {
+ if (!mHasFeature) {
+ return;
+ }
synchronized (this) {
// This API can only be called by an active device admin,
// so try to retrieve it to check that the caller is one.
}
public void wipeData(int flags, final int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
// This API can only be called by an active device admin,
}
public void getRemoveWarning(ComponentName comp, final RemoteCallback result, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BIND_DEVICE_ADMIN, null);
public void setActivePasswordState(int quality, int length, int letters, int uppercase,
int lowercase, int numbers, int symbols, int nonletter, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BIND_DEVICE_ADMIN, null);
try {
policy.mFailedPasswordAttempts++;
saveSettingsLocked(userHandle);
- int max = getMaximumFailedPasswordsForWipe(null, userHandle);
- if (max > 0 && policy.mFailedPasswordAttempts >= max) {
- wipeDeviceOrUserLocked(0, userHandle);
+ if (mHasFeature) {
+ int max = getMaximumFailedPasswordsForWipe(null, userHandle);
+ if (max > 0 && policy.mFailedPasswordAttempts >= max) {
+ wipeDeviceOrUserLocked(0, userHandle);
+ }
+ sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_FAILED,
+ DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
}
- sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_FAILED,
- DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
} finally {
Binder.restoreCallingIdentity(ident);
}
policy.mFailedPasswordAttempts = 0;
policy.mPasswordOwner = -1;
saveSettingsLocked(userHandle);
- sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED,
- DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
+ if (mHasFeature) {
+ sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED,
+ DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
+ }
} finally {
Binder.restoreCallingIdentity(ident);
}
public ComponentName setGlobalProxy(ComponentName who, String proxySpec,
String exclusionList, int userHandle) {
+ if (!mHasFeature) {
+ return null;
+ }
enforceCrossUserPermission(userHandle);
synchronized(this) {
if (who == null) {
}
public ComponentName getGlobalProxyAdmin(int userHandle) {
+ if (!mHasFeature) {
+ return null;
+ }
enforceCrossUserPermission(userHandle);
synchronized(this) {
DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
* status (for all admins).
*/
public int setStorageEncryption(ComponentName who, boolean encrypt, int userHandle) {
+ if (!mHasFeature) {
+ return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
// Check for permissions
* active admins.
*/
public boolean getStorageEncryption(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return false;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
// Check for permissions if a particular caller is specified
* Get the current encryption status of the device.
*/
public int getStorageEncryptionStatus(int userHandle) {
+ if (!mHasFeature) {
+ // Ok to return current status.
+ }
enforceCrossUserPermission(userHandle);
return getEncryptionStatus();
}
* Disables all device cameras according to the specified admin.
*/
public void setCameraDisabled(ComponentName who, boolean disabled, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
* active admins.
*/
public boolean getCameraDisabled(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return false;
+ }
synchronized (this) {
if (who != null) {
ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
* Selectively disable keyguard features.
*/
public void setKeyguardDisabledFeatures(ComponentName who, int which, int userHandle) {
+ if (!mHasFeature) {
+ return;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who == null) {
* or the aggregate of all active admins if who is null.
*/
public int getKeyguardDisabledFeatures(ComponentName who, int userHandle) {
+ if (!mHasFeature) {
+ return 0;
+ }
enforceCrossUserPermission(userHandle);
synchronized (this) {
if (who != null) {
@Override
public boolean setDeviceOwner(String packageName, String ownerName) {
+ if (!mHasFeature) {
+ return false;
+ }
if (packageName == null
|| !DeviceOwner.isInstalled(packageName, mContext.getPackageManager())) {
throw new IllegalArgumentException("Invalid package name " + packageName
@Override
public boolean isDeviceOwner(String packageName) {
+ if (!mHasFeature) {
+ return false;
+ }
synchronized (this) {
return mDeviceOwner != null
&& mDeviceOwner.getPackageName().equals(packageName);
@Override
public String getDeviceOwner() {
+ if (!mHasFeature) {
+ return null;
+ }
synchronized (this) {
if (mDeviceOwner != null) {
return mDeviceOwner.getPackageName();
@Override
public String getDeviceOwnerName() {
+ if (!mHasFeature) {
+ return null;
+ }
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
synchronized (this) {
if (mDeviceOwner != null) {