summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/DevicePolicyManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/DevicePolicyManagerService.java')
-rw-r--r--services/java/com/android/server/DevicePolicyManagerService.java2942
1 files changed, 0 insertions, 2942 deletions
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
deleted file mode 100644
index 2bb99d6..0000000
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ /dev/null
@@ -1,2942 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server;
-
-import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
-
-import com.android.internal.R;
-import com.android.internal.os.storage.ExternalStorageFormatter;
-import com.android.internal.util.FastXmlSerializer;
-import com.android.internal.util.JournaledFile;
-import com.android.internal.util.XmlUtils;
-import com.android.internal.widget.LockPatternUtils;
-import com.android.org.conscrypt.TrustedCertificateStore;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-import org.xmlpull.v1.XmlSerializer;
-
-import android.app.Activity;
-import android.app.ActivityManagerNative;
-import android.app.AlarmManager;
-import android.app.AppGlobals;
-import android.app.INotificationManager;
-import android.app.Notification;
-import android.app.NotificationManager;
-import android.app.PendingIntent;
-import android.app.admin.DeviceAdminInfo;
-import android.app.admin.DeviceAdminReceiver;
-import android.app.admin.DevicePolicyManager;
-import android.app.admin.IDevicePolicyManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.Signature;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.content.pm.UserInfo;
-import android.net.ProxyProperties;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IPowerManager;
-import android.os.PowerManager;
-import android.os.Process;
-import android.os.RecoverySystem;
-import android.os.RemoteCallback;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.provider.Settings;
-import android.security.Credentials;
-import android.security.IKeyChainService;
-import android.security.KeyChain;
-import android.security.KeyChain.KeyChainConnection;
-import android.util.AtomicFile;
-import android.util.Log;
-import android.util.PrintWriterPrinter;
-import android.util.Printer;
-import android.util.Slog;
-import android.util.SparseArray;
-import android.util.Xml;
-import android.view.IWindowManager;
-import android.view.WindowManagerPolicy;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
-import java.io.FileDescriptor;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.security.KeyStore.TrustedCertificateEntry;
-import java.security.cert.CertificateException;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.text.DateFormat;
-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;
-import java.util.Set;
-
-/**
- * Implementation of the device policy APIs.
- */
-public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
-
- private static final String TAG = "DevicePolicyManagerService";
-
- private static final String DEVICE_POLICIES_XML = "device_policies.xml";
-
- private static final int REQUEST_EXPIRE_PASSWORD = 5571;
-
- private static final long MS_PER_DAY = 86400 * 1000;
-
- private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * MS_PER_DAY; // 5 days, in ms
-
- protected static final String ACTION_EXPIRED_PASSWORD_NOTIFICATION
- = "com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION";
-
- private static final int MONITORING_CERT_NOTIFICATION_ID = R.string.ssl_ca_cert_warning;
-
- private static final boolean DBG = false;
-
- final Context mContext;
- final PowerManager.WakeLock mWakeLock;
-
- IPowerManager mIPowerManager;
- IWindowManager mIWindowManager;
- NotificationManager mNotificationManager;
-
- 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;
- int mActivePasswordUpperCase = 0;
- int mActivePasswordLowerCase = 0;
- int mActivePasswordLetters = 0;
- int mActivePasswordNumeric = 0;
- int mActivePasswordSymbols = 0;
- int mActivePasswordNonLetter = 0;
- int mFailedPasswordAttempts = 0;
-
- int mUserHandle;;
- int mPasswordOwner = -1;
- long mLastMaximumTimeToLock = -1;
-
- final HashMap<ComponentName, ActiveAdmin> mAdminMap
- = new HashMap<ComponentName, ActiveAdmin>();
- final ArrayList<ActiveAdmin> mAdminList
- = new ArrayList<ActiveAdmin>();
-
- public DevicePolicyData(int userHandle) {
- mUserHandle = userHandle;
- }
- }
-
- final SparseArray<DevicePolicyData> mUserData = new SparseArray<DevicePolicyData>();
-
- Handler mHandler = new Handler();
-
- BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
- getSendingUserId());
- if (Intent.ACTION_BOOT_COMPLETED.equals(action)
- || ACTION_EXPIRED_PASSWORD_NOTIFICATION.equals(action)) {
- if (DBG) Slog.v(TAG, "Sending password expiration notifications for action "
- + action + " for user " + userHandle);
- mHandler.post(new Runnable() {
- public void run() {
- handlePasswordExpirationNotification(getUserData(userHandle));
- }
- });
- }
- if (Intent.ACTION_BOOT_COMPLETED.equals(action)
- || KeyChain.ACTION_STORAGE_CHANGED.equals(action)) {
- manageMonitoringCertificateNotification(intent);
- }
- if (Intent.ACTION_USER_REMOVED.equals(action)) {
- removeUserData(userHandle);
- } else if (Intent.ACTION_USER_STARTED.equals(action)
- || Intent.ACTION_PACKAGE_CHANGED.equals(action)
- || Intent.ACTION_PACKAGE_REMOVED.equals(action)
- || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
-
- if (Intent.ACTION_USER_STARTED.equals(action)) {
- // Reset the policy data
- synchronized (DevicePolicyManagerService.this) {
- mUserData.remove(userHandle);
- }
- }
-
- handlePackagesChanged(userHandle);
- }
- }
- };
-
- static class ActiveAdmin {
- final DeviceAdminInfo info;
-
- int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
-
- static final int DEF_MINIMUM_PASSWORD_LENGTH = 0;
- int minimumPasswordLength = DEF_MINIMUM_PASSWORD_LENGTH;
-
- static final int DEF_PASSWORD_HISTORY_LENGTH = 0;
- int passwordHistoryLength = DEF_PASSWORD_HISTORY_LENGTH;
-
- static final int DEF_MINIMUM_PASSWORD_UPPER_CASE = 0;
- int minimumPasswordUpperCase = DEF_MINIMUM_PASSWORD_UPPER_CASE;
-
- static final int DEF_MINIMUM_PASSWORD_LOWER_CASE = 0;
- int minimumPasswordLowerCase = DEF_MINIMUM_PASSWORD_LOWER_CASE;
-
- static final int DEF_MINIMUM_PASSWORD_LETTERS = 1;
- int minimumPasswordLetters = DEF_MINIMUM_PASSWORD_LETTERS;
-
- static final int DEF_MINIMUM_PASSWORD_NUMERIC = 1;
- int minimumPasswordNumeric = DEF_MINIMUM_PASSWORD_NUMERIC;
-
- static final int DEF_MINIMUM_PASSWORD_SYMBOLS = 1;
- int minimumPasswordSymbols = DEF_MINIMUM_PASSWORD_SYMBOLS;
-
- static final int DEF_MINIMUM_PASSWORD_NON_LETTER = 0;
- int minimumPasswordNonLetter = DEF_MINIMUM_PASSWORD_NON_LETTER;
-
- static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0;
- long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK;
-
- static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0;
- int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE;
-
- static final long DEF_PASSWORD_EXPIRATION_TIMEOUT = 0;
- long passwordExpirationTimeout = DEF_PASSWORD_EXPIRATION_TIMEOUT;
-
- static final long DEF_PASSWORD_EXPIRATION_DATE = 0;
- long passwordExpirationDate = DEF_PASSWORD_EXPIRATION_DATE;
-
- static final int DEF_KEYGUARD_FEATURES_DISABLED = 0; // none
- int disabledKeyguardFeatures = DEF_KEYGUARD_FEATURES_DISABLED;
-
- boolean encryptionRequested = false;
- boolean disableCamera = false;
-
- // TODO: review implementation decisions with frameworks team
- boolean specifiesGlobalProxy = false;
- String globalProxySpec = null;
- String globalProxyExclusionList = null;
-
- ActiveAdmin(DeviceAdminInfo _info) {
- info = _info;
- }
-
- int getUid() { return info.getActivityInfo().applicationInfo.uid; }
-
- public UserHandle getUserHandle() {
- return new UserHandle(UserHandle.getUserId(info.getActivityInfo().applicationInfo.uid));
- }
-
- void writeToXml(XmlSerializer out)
- throws IllegalArgumentException, IllegalStateException, IOException {
- out.startTag(null, "policies");
- info.writePoliciesToXml(out);
- out.endTag(null, "policies");
- if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
- out.startTag(null, "password-quality");
- out.attribute(null, "value", Integer.toString(passwordQuality));
- out.endTag(null, "password-quality");
- if (minimumPasswordLength != DEF_MINIMUM_PASSWORD_LENGTH) {
- out.startTag(null, "min-password-length");
- out.attribute(null, "value", Integer.toString(minimumPasswordLength));
- out.endTag(null, "min-password-length");
- }
- if(passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) {
- out.startTag(null, "password-history-length");
- out.attribute(null, "value", Integer.toString(passwordHistoryLength));
- out.endTag(null, "password-history-length");
- }
- if (minimumPasswordUpperCase != DEF_MINIMUM_PASSWORD_UPPER_CASE) {
- out.startTag(null, "min-password-uppercase");
- out.attribute(null, "value", Integer.toString(minimumPasswordUpperCase));
- out.endTag(null, "min-password-uppercase");
- }
- if (minimumPasswordLowerCase != DEF_MINIMUM_PASSWORD_LOWER_CASE) {
- out.startTag(null, "min-password-lowercase");
- out.attribute(null, "value", Integer.toString(minimumPasswordLowerCase));
- out.endTag(null, "min-password-lowercase");
- }
- if (minimumPasswordLetters != DEF_MINIMUM_PASSWORD_LETTERS) {
- out.startTag(null, "min-password-letters");
- out.attribute(null, "value", Integer.toString(minimumPasswordLetters));
- out.endTag(null, "min-password-letters");
- }
- if (minimumPasswordNumeric != DEF_MINIMUM_PASSWORD_NUMERIC) {
- out.startTag(null, "min-password-numeric");
- out.attribute(null, "value", Integer.toString(minimumPasswordNumeric));
- out.endTag(null, "min-password-numeric");
- }
- if (minimumPasswordSymbols != DEF_MINIMUM_PASSWORD_SYMBOLS) {
- out.startTag(null, "min-password-symbols");
- out.attribute(null, "value", Integer.toString(minimumPasswordSymbols));
- out.endTag(null, "min-password-symbols");
- }
- if (minimumPasswordNonLetter > DEF_MINIMUM_PASSWORD_NON_LETTER) {
- out.startTag(null, "min-password-nonletter");
- out.attribute(null, "value", Integer.toString(minimumPasswordNonLetter));
- out.endTag(null, "min-password-nonletter");
- }
- }
- if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) {
- out.startTag(null, "max-time-to-unlock");
- out.attribute(null, "value", Long.toString(maximumTimeToUnlock));
- out.endTag(null, "max-time-to-unlock");
- }
- if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
- out.startTag(null, "max-failed-password-wipe");
- out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe));
- out.endTag(null, "max-failed-password-wipe");
- }
- if (specifiesGlobalProxy) {
- out.startTag(null, "specifies-global-proxy");
- out.attribute(null, "value", Boolean.toString(specifiesGlobalProxy));
- out.endTag(null, "specifies_global_proxy");
- if (globalProxySpec != null) {
- out.startTag(null, "global-proxy-spec");
- out.attribute(null, "value", globalProxySpec);
- out.endTag(null, "global-proxy-spec");
- }
- if (globalProxyExclusionList != null) {
- out.startTag(null, "global-proxy-exclusion-list");
- out.attribute(null, "value", globalProxyExclusionList);
- out.endTag(null, "global-proxy-exclusion-list");
- }
- }
- if (passwordExpirationTimeout != DEF_PASSWORD_EXPIRATION_TIMEOUT) {
- out.startTag(null, "password-expiration-timeout");
- out.attribute(null, "value", Long.toString(passwordExpirationTimeout));
- out.endTag(null, "password-expiration-timeout");
- }
- if (passwordExpirationDate != DEF_PASSWORD_EXPIRATION_DATE) {
- out.startTag(null, "password-expiration-date");
- out.attribute(null, "value", Long.toString(passwordExpirationDate));
- out.endTag(null, "password-expiration-date");
- }
- if (encryptionRequested) {
- out.startTag(null, "encryption-requested");
- out.attribute(null, "value", Boolean.toString(encryptionRequested));
- out.endTag(null, "encryption-requested");
- }
- if (disableCamera) {
- out.startTag(null, "disable-camera");
- out.attribute(null, "value", Boolean.toString(disableCamera));
- out.endTag(null, "disable-camera");
- }
- if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
- out.startTag(null, "disable-keyguard-features");
- out.attribute(null, "value", Integer.toString(disabledKeyguardFeatures));
- out.endTag(null, "disable-keyguard-features");
- }
- }
-
- void readFromXml(XmlPullParser parser)
- throws XmlPullParserException, IOException {
- int outerDepth = parser.getDepth();
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
- String tag = parser.getName();
- if ("policies".equals(tag)) {
- info.readPoliciesFromXml(parser);
- } else if ("password-quality".equals(tag)) {
- passwordQuality = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- } else if ("min-password-length".equals(tag)) {
- minimumPasswordLength = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- } else if ("password-history-length".equals(tag)) {
- passwordHistoryLength = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- } else if ("min-password-uppercase".equals(tag)) {
- minimumPasswordUpperCase = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- } else if ("min-password-lowercase".equals(tag)) {
- minimumPasswordLowerCase = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- } else if ("min-password-letters".equals(tag)) {
- minimumPasswordLetters = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- } else if ("min-password-numeric".equals(tag)) {
- minimumPasswordNumeric = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- } else if ("min-password-symbols".equals(tag)) {
- minimumPasswordSymbols = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- } else if ("min-password-nonletter".equals(tag)) {
- minimumPasswordNonLetter = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- } else if ("max-time-to-unlock".equals(tag)) {
- maximumTimeToUnlock = Long.parseLong(
- parser.getAttributeValue(null, "value"));
- } else if ("max-failed-password-wipe".equals(tag)) {
- maximumFailedPasswordsForWipe = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- } else if ("specifies-global-proxy".equals(tag)) {
- specifiesGlobalProxy = Boolean.parseBoolean(
- parser.getAttributeValue(null, "value"));
- } else if ("global-proxy-spec".equals(tag)) {
- globalProxySpec =
- parser.getAttributeValue(null, "value");
- } else if ("global-proxy-exclusion-list".equals(tag)) {
- globalProxyExclusionList =
- parser.getAttributeValue(null, "value");
- } else if ("password-expiration-timeout".equals(tag)) {
- passwordExpirationTimeout = Long.parseLong(
- parser.getAttributeValue(null, "value"));
- } else if ("password-expiration-date".equals(tag)) {
- passwordExpirationDate = Long.parseLong(
- parser.getAttributeValue(null, "value"));
- } else if ("encryption-requested".equals(tag)) {
- encryptionRequested = Boolean.parseBoolean(
- parser.getAttributeValue(null, "value"));
- } else if ("disable-camera".equals(tag)) {
- disableCamera = Boolean.parseBoolean(
- parser.getAttributeValue(null, "value"));
- } else if ("disable-keyguard-features".equals(tag)) {
- disabledKeyguardFeatures = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- } else {
- Slog.w(TAG, "Unknown admin tag: " + tag);
- }
- XmlUtils.skipCurrentTag(parser);
- }
- }
-
- void dump(String prefix, PrintWriter pw) {
- pw.print(prefix); pw.print("uid="); pw.println(getUid());
- pw.print(prefix); pw.println("policies:");
- ArrayList<DeviceAdminInfo.PolicyInfo> pols = info.getUsedPolicies();
- if (pols != null) {
- for (int i=0; i<pols.size(); i++) {
- pw.print(prefix); pw.print(" "); pw.println(pols.get(i).tag);
- }
- }
- pw.print(prefix); pw.print("passwordQuality=0x");
- pw.println(Integer.toHexString(passwordQuality));
- pw.print(prefix); pw.print("minimumPasswordLength=");
- pw.println(minimumPasswordLength);
- pw.print(prefix); pw.print("passwordHistoryLength=");
- pw.println(passwordHistoryLength);
- pw.print(prefix); pw.print("minimumPasswordUpperCase=");
- pw.println(minimumPasswordUpperCase);
- pw.print(prefix); pw.print("minimumPasswordLowerCase=");
- pw.println(minimumPasswordLowerCase);
- pw.print(prefix); pw.print("minimumPasswordLetters=");
- pw.println(minimumPasswordLetters);
- pw.print(prefix); pw.print("minimumPasswordNumeric=");
- pw.println(minimumPasswordNumeric);
- pw.print(prefix); pw.print("minimumPasswordSymbols=");
- pw.println(minimumPasswordSymbols);
- pw.print(prefix); pw.print("minimumPasswordNonLetter=");
- pw.println(minimumPasswordNonLetter);
- pw.print(prefix); pw.print("maximumTimeToUnlock=");
- pw.println(maximumTimeToUnlock);
- pw.print(prefix); pw.print("maximumFailedPasswordsForWipe=");
- pw.println(maximumFailedPasswordsForWipe);
- pw.print(prefix); pw.print("specifiesGlobalProxy=");
- pw.println(specifiesGlobalProxy);
- pw.print(prefix); pw.print("passwordExpirationTimeout=");
- pw.println(passwordExpirationTimeout);
- pw.print(prefix); pw.print("passwordExpirationDate=");
- pw.println(passwordExpirationDate);
- if (globalProxySpec != null) {
- pw.print(prefix); pw.print("globalProxySpec=");
- pw.println(globalProxySpec);
- }
- if (globalProxyExclusionList != null) {
- pw.print(prefix); pw.print("globalProxyEclusionList=");
- pw.println(globalProxyExclusionList);
- }
- pw.print(prefix); pw.print("encryptionRequested=");
- pw.println(encryptionRequested);
- pw.print(prefix); pw.print("disableCamera=");
- pw.println(disableCamera);
- pw.print(prefix); pw.print("disabledKeyguardFeatures=");
- pw.println(disabledKeyguardFeatures);
- }
- }
-
- private void handlePackagesChanged(int userHandle) {
- boolean removed = false;
- if (DBG) Slog.d(TAG, "Handling package changes for user " + userHandle);
- DevicePolicyData policy = getUserData(userHandle);
- IPackageManager pm = AppGlobals.getPackageManager();
- for (int i = policy.mAdminList.size() - 1; i >= 0; i--) {
- ActiveAdmin aa = policy.mAdminList.get(i);
- try {
- if (pm.getPackageInfo(aa.info.getPackageName(), 0, userHandle) == null
- || pm.getReceiverInfo(aa.info.getComponent(), 0, userHandle) == null) {
- removed = true;
- policy.mAdminList.remove(i);
- policy.mAdminMap.remove(aa.info.getComponent());
- }
- } catch (RemoteException re) {
- // Shouldn't happen
- }
- }
- if (removed) {
- validatePasswordOwnerLocked(policy);
- syncDeviceCapabilitiesLocked(policy);
- saveSettingsLocked(policy.mUserHandle);
- }
- }
-
- /**
- * Instantiates the service.
- */
- 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);
- filter.addAction(Intent.ACTION_USER_REMOVED);
- filter.addAction(Intent.ACTION_USER_STARTED);
- filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
- context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
- filter = new IntentFilter();
- filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
- filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
- filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
- filter.addAction(Intent.ACTION_PACKAGE_ADDED);
- filter.addDataScheme("package");
- context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
- }
-
- /**
- * Creates and loads the policy data from xml.
- * @param userHandle the user for whom to load the policy data
- * @return
- */
- DevicePolicyData getUserData(int userHandle) {
- synchronized (this) {
- DevicePolicyData policy = mUserData.get(userHandle);
- if (policy == null) {
- policy = new DevicePolicyData(userHandle);
- mUserData.append(userHandle, policy);
- loadSettingsLocked(policy, userHandle);
- }
- return policy;
- }
- }
-
- void removeUserData(int userHandle) {
- synchronized (this) {
- if (userHandle == UserHandle.USER_OWNER) {
- Slog.w(TAG, "Tried to remove device policy file for user 0! Ignoring.");
- return;
- }
- DevicePolicyData policy = mUserData.get(userHandle);
- if (policy != null) {
- mUserData.remove(userHandle);
- }
- File policyFile = new File(Environment.getUserSystemDirectory(userHandle),
- DEVICE_POLICIES_XML);
- policyFile.delete();
- Slog.i(TAG, "Removed device policy file " + policyFile.getAbsolutePath());
- }
- }
-
- void loadDeviceOwner() {
- synchronized (this) {
- if (DeviceOwner.isRegistered()) {
- mDeviceOwner = new DeviceOwner();
- }
- }
- }
-
- /**
- * Set an alarm for an upcoming event - expiration warning, expiration, or post-expiration
- * reminders. Clears alarm if no expirations are configured.
- */
- protected void setExpirationAlarmCheckLocked(Context context, DevicePolicyData policy) {
- final long expiration = getPasswordExpirationLocked(null, policy.mUserHandle);
- final long now = System.currentTimeMillis();
- final long timeToExpire = expiration - now;
- final long alarmTime;
- if (expiration == 0) {
- // No expirations are currently configured: Cancel alarm.
- alarmTime = 0;
- } else if (timeToExpire <= 0) {
- // The password has already expired: Repeat every 24 hours.
- alarmTime = now + MS_PER_DAY;
- } else {
- // Selecting the next alarm time: Roll forward to the next 24 hour multiple before
- // the expiration time.
- long alarmInterval = timeToExpire % MS_PER_DAY;
- if (alarmInterval == 0) {
- alarmInterval = MS_PER_DAY;
- }
- alarmTime = now + alarmInterval;
- }
-
- long token = Binder.clearCallingIdentity();
- try {
- AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
- PendingIntent pi = PendingIntent.getBroadcastAsUser(context, REQUEST_EXPIRE_PASSWORD,
- new Intent(ACTION_EXPIRED_PASSWORD_NOTIFICATION),
- PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT,
- new UserHandle(policy.mUserHandle));
- am.cancel(pi);
- if (alarmTime != 0) {
- am.set(AlarmManager.RTC, alarmTime, pi);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
-
- private IPowerManager getIPowerManager() {
- if (mIPowerManager == null) {
- IBinder b = ServiceManager.getService(Context.POWER_SERVICE);
- mIPowerManager = IPowerManager.Stub.asInterface(b);
- }
- return mIPowerManager;
- }
-
- private IWindowManager getWindowManager() {
- if (mIWindowManager == null) {
- IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
- mIWindowManager = IWindowManager.Stub.asInterface(b);
- }
- return mIWindowManager;
- }
-
- private NotificationManager getNotificationManager() {
- if (mNotificationManager == null) {
- mNotificationManager =
- (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
- }
- return mNotificationManager;
- }
-
- ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle) {
- ActiveAdmin admin = getUserData(userHandle).mAdminMap.get(who);
- if (admin != null
- && who.getPackageName().equals(admin.info.getActivityInfo().packageName)
- && who.getClassName().equals(admin.info.getActivityInfo().name)) {
- return admin;
- }
- return null;
- }
-
- ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy)
- throws SecurityException {
- final int callingUid = Binder.getCallingUid();
- final int userHandle = UserHandle.getUserId(callingUid);
- final DevicePolicyData policy = getUserData(userHandle);
- if (who != null) {
- ActiveAdmin admin = policy.mAdminMap.get(who);
- if (admin == null) {
- throw new SecurityException("No active admin " + who);
- }
- if (admin.getUid() != callingUid) {
- throw new SecurityException("Admin " + who + " is not owned by uid "
- + Binder.getCallingUid());
- }
- if (!admin.info.usesPolicy(reqPolicy)) {
- throw new SecurityException("Admin " + admin.info.getComponent()
- + " did not specify uses-policy for: "
- + admin.info.getTagForPolicy(reqPolicy));
- }
- return admin;
- } else {
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (admin.getUid() == callingUid && admin.info.usesPolicy(reqPolicy)) {
- return admin;
- }
- }
- throw new SecurityException("No active admin owned by uid "
- + Binder.getCallingUid() + " for policy #" + reqPolicy);
- }
- }
-
- void sendAdminCommandLocked(ActiveAdmin admin, String action) {
- sendAdminCommandLocked(admin, action, null);
- }
-
- void sendAdminCommandLocked(ActiveAdmin admin, String action, BroadcastReceiver result) {
- Intent intent = new Intent(action);
- intent.setComponent(admin.info.getComponent());
- if (action.equals(DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING)) {
- intent.putExtra("expiration", admin.passwordExpirationDate);
- }
- if (result != null) {
- mContext.sendOrderedBroadcastAsUser(intent, admin.getUserHandle(),
- null, result, mHandler, Activity.RESULT_OK, null, null);
- } else {
- mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
- }
- }
-
- void sendAdminCommandLocked(String action, int reqPolicy, int userHandle) {
- final DevicePolicyData policy = getUserData(userHandle);
- final int count = policy.mAdminList.size();
- if (count > 0) {
- for (int i = 0; i < count; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (admin.info.usesPolicy(reqPolicy)) {
- sendAdminCommandLocked(admin, action);
- }
- }
- }
- }
-
- void removeActiveAdminLocked(final ComponentName adminReceiver, int userHandle) {
- final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
- if (admin != null) {
- sendAdminCommandLocked(admin,
- DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED,
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- synchronized (DevicePolicyManagerService.this) {
- int userHandle = admin.getUserHandle().getIdentifier();
- DevicePolicyData policy = getUserData(userHandle);
- boolean doProxyCleanup = admin.info.usesPolicy(
- DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
- policy.mAdminList.remove(admin);
- policy.mAdminMap.remove(adminReceiver);
- validatePasswordOwnerLocked(policy);
- syncDeviceCapabilitiesLocked(policy);
- if (doProxyCleanup) {
- resetGlobalProxyLocked(getUserData(userHandle));
- }
- saveSettingsLocked(userHandle);
- updateMaximumTimeToLockLocked(policy);
- }
- }
- });
- }
- }
-
- public DeviceAdminInfo findAdmin(ComponentName adminName, int userHandle) {
- if (!mHasFeature) {
- return null;
- }
- enforceCrossUserPermission(userHandle);
- Intent resolveIntent = new Intent();
- resolveIntent.setComponent(adminName);
- List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceivers(
- resolveIntent,
- PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
- userHandle);
- if (infos == null || infos.size() <= 0) {
- throw new IllegalArgumentException("Unknown admin: " + adminName);
- }
-
- try {
- return new DeviceAdminInfo(mContext, infos.get(0));
- } catch (XmlPullParserException e) {
- Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e);
- return null;
- } catch (IOException e) {
- Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e);
- return null;
- }
- }
-
- private static JournaledFile makeJournaledFile(int userHandle) {
- final String base = userHandle == 0
- ? "/data/system/" + DEVICE_POLICIES_XML
- : new File(Environment.getUserSystemDirectory(userHandle), DEVICE_POLICIES_XML)
- .getAbsolutePath();
- return new JournaledFile(new File(base), new File(base + ".tmp"));
- }
-
- private void saveSettingsLocked(int userHandle) {
- DevicePolicyData policy = getUserData(userHandle);
- JournaledFile journal = makeJournaledFile(userHandle);
- FileOutputStream stream = null;
- try {
- stream = new FileOutputStream(journal.chooseForWrite(), false);
- XmlSerializer out = new FastXmlSerializer();
- out.setOutput(stream, "utf-8");
- out.startDocument(null, true);
-
- out.startTag(null, "policies");
-
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin ap = policy.mAdminList.get(i);
- if (ap != null) {
- out.startTag(null, "admin");
- out.attribute(null, "name", ap.info.getComponent().flattenToString());
- ap.writeToXml(out);
- out.endTag(null, "admin");
- }
- }
-
- if (policy.mPasswordOwner >= 0) {
- out.startTag(null, "password-owner");
- out.attribute(null, "value", Integer.toString(policy.mPasswordOwner));
- out.endTag(null, "password-owner");
- }
-
- if (policy.mFailedPasswordAttempts != 0) {
- out.startTag(null, "failed-password-attempts");
- out.attribute(null, "value", Integer.toString(policy.mFailedPasswordAttempts));
- out.endTag(null, "failed-password-attempts");
- }
-
- if (policy.mActivePasswordQuality != 0 || policy.mActivePasswordLength != 0
- || policy.mActivePasswordUpperCase != 0 || policy.mActivePasswordLowerCase != 0
- || policy.mActivePasswordLetters != 0 || policy.mActivePasswordNumeric != 0
- || policy.mActivePasswordSymbols != 0 || policy.mActivePasswordNonLetter != 0) {
- out.startTag(null, "active-password");
- out.attribute(null, "quality", Integer.toString(policy.mActivePasswordQuality));
- out.attribute(null, "length", Integer.toString(policy.mActivePasswordLength));
- out.attribute(null, "uppercase", Integer.toString(policy.mActivePasswordUpperCase));
- out.attribute(null, "lowercase", Integer.toString(policy.mActivePasswordLowerCase));
- out.attribute(null, "letters", Integer.toString(policy.mActivePasswordLetters));
- out.attribute(null, "numeric", Integer
- .toString(policy.mActivePasswordNumeric));
- out.attribute(null, "symbols", Integer.toString(policy.mActivePasswordSymbols));
- out.attribute(null, "nonletter", Integer.toString(policy.mActivePasswordNonLetter));
- out.endTag(null, "active-password");
- }
-
- out.endTag(null, "policies");
-
- out.endDocument();
- stream.close();
- journal.commit();
- sendChangedNotification(userHandle);
- } catch (IOException e) {
- try {
- if (stream != null) {
- stream.close();
- }
- } catch (IOException ex) {
- // Ignore
- }
- journal.rollback();
- }
- }
-
- private void sendChangedNotification(int userHandle) {
- Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
- intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- long ident = Binder.clearCallingIdentity();
- try {
- mContext.sendBroadcastAsUser(intent, new UserHandle(userHandle));
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- private void loadSettingsLocked(DevicePolicyData policy, int userHandle) {
- JournaledFile journal = makeJournaledFile(userHandle);
- FileInputStream stream = null;
- File file = journal.chooseForRead();
- try {
- stream = new FileInputStream(file);
- XmlPullParser parser = Xml.newPullParser();
- parser.setInput(stream, null);
-
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && type != XmlPullParser.START_TAG) {
- }
- String tag = parser.getName();
- if (!"policies".equals(tag)) {
- throw new XmlPullParserException(
- "Settings do not start with policies tag: found " + tag);
- }
- type = parser.next();
- int outerDepth = parser.getDepth();
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
- tag = parser.getName();
- if ("admin".equals(tag)) {
- String name = parser.getAttributeValue(null, "name");
- try {
- DeviceAdminInfo dai = findAdmin(
- ComponentName.unflattenFromString(name), userHandle);
- if (DBG && (UserHandle.getUserId(dai.getActivityInfo().applicationInfo.uid)
- != userHandle)) {
- Slog.w(TAG, "findAdmin returned an incorrect uid "
- + dai.getActivityInfo().applicationInfo.uid + " for user "
- + userHandle);
- }
- if (dai != null) {
- ActiveAdmin ap = new ActiveAdmin(dai);
- ap.readFromXml(parser);
- policy.mAdminMap.put(ap.info.getComponent(), ap);
- policy.mAdminList.add(ap);
- }
- } catch (RuntimeException e) {
- Slog.w(TAG, "Failed loading admin " + name, e);
- }
- } else if ("failed-password-attempts".equals(tag)) {
- policy.mFailedPasswordAttempts = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- XmlUtils.skipCurrentTag(parser);
- } else if ("password-owner".equals(tag)) {
- policy.mPasswordOwner = Integer.parseInt(
- parser.getAttributeValue(null, "value"));
- XmlUtils.skipCurrentTag(parser);
- } else if ("active-password".equals(tag)) {
- policy.mActivePasswordQuality = Integer.parseInt(
- parser.getAttributeValue(null, "quality"));
- policy.mActivePasswordLength = Integer.parseInt(
- parser.getAttributeValue(null, "length"));
- policy.mActivePasswordUpperCase = Integer.parseInt(
- parser.getAttributeValue(null, "uppercase"));
- policy.mActivePasswordLowerCase = Integer.parseInt(
- parser.getAttributeValue(null, "lowercase"));
- policy.mActivePasswordLetters = Integer.parseInt(
- parser.getAttributeValue(null, "letters"));
- policy.mActivePasswordNumeric = Integer.parseInt(
- parser.getAttributeValue(null, "numeric"));
- policy.mActivePasswordSymbols = Integer.parseInt(
- parser.getAttributeValue(null, "symbols"));
- policy.mActivePasswordNonLetter = Integer.parseInt(
- parser.getAttributeValue(null, "nonletter"));
- XmlUtils.skipCurrentTag(parser);
- } else {
- Slog.w(TAG, "Unknown tag: " + tag);
- XmlUtils.skipCurrentTag(parser);
- }
- }
- } catch (NullPointerException e) {
- Slog.w(TAG, "failed parsing " + file + " " + e);
- } catch (NumberFormatException e) {
- Slog.w(TAG, "failed parsing " + file + " " + e);
- } catch (XmlPullParserException e) {
- Slog.w(TAG, "failed parsing " + file + " " + e);
- } catch (FileNotFoundException e) {
- // Don't be noisy, this is normal if we haven't defined any policies.
- } catch (IOException e) {
- Slog.w(TAG, "failed parsing " + file + " " + e);
- } catch (IndexOutOfBoundsException e) {
- Slog.w(TAG, "failed parsing " + file + " " + e);
- }
- try {
- if (stream != null) {
- stream.close();
- }
- } catch (IOException e) {
- // Ignore
- }
-
- // Validate that what we stored for the password quality matches
- // sufficiently what is currently set. Note that this is only
- // a sanity check in case the two get out of sync; this should
- // never normally happen.
- LockPatternUtils utils = new LockPatternUtils(mContext);
- if (utils.getActivePasswordQuality() < policy.mActivePasswordQuality) {
- Slog.w(TAG, "Active password quality 0x"
- + Integer.toHexString(policy.mActivePasswordQuality)
- + " does not match actual quality 0x"
- + Integer.toHexString(utils.getActivePasswordQuality()));
- policy.mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
- policy.mActivePasswordLength = 0;
- policy.mActivePasswordUpperCase = 0;
- policy.mActivePasswordLowerCase = 0;
- policy.mActivePasswordLetters = 0;
- policy.mActivePasswordNumeric = 0;
- policy.mActivePasswordSymbols = 0;
- policy.mActivePasswordNonLetter = 0;
- }
-
- validatePasswordOwnerLocked(policy);
- syncDeviceCapabilitiesLocked(policy);
- updateMaximumTimeToLockLocked(policy);
- }
-
- static void validateQualityConstant(int quality) {
- switch (quality) {
- case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
- case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK:
- case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
- case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
- case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
- case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
- return;
- }
- throw new IllegalArgumentException("Invalid quality constant: 0x"
- + Integer.toHexString(quality));
- }
-
- void validatePasswordOwnerLocked(DevicePolicyData policy) {
- if (policy.mPasswordOwner >= 0) {
- boolean haveOwner = false;
- for (int i = policy.mAdminList.size() - 1; i >= 0; i--) {
- if (policy.mAdminList.get(i).getUid() == policy.mPasswordOwner) {
- haveOwner = true;
- break;
- }
- }
- if (!haveOwner) {
- Slog.w(TAG, "Previous password owner " + policy.mPasswordOwner
- + " no longer active; disabling");
- policy.mPasswordOwner = -1;
- }
- }
- }
-
- /**
- * Pushes down policy information to the system for any policies related to general device
- * capabilities that need to be enforced by lower level services (e.g. Camera services).
- */
- void syncDeviceCapabilitiesLocked(DevicePolicyData policy) {
- // Ensure the status of the camera is synced down to the system. Interested native services
- // should monitor this value and act accordingly.
- boolean systemState = SystemProperties.getBoolean(SYSTEM_PROP_DISABLE_CAMERA, false);
- boolean cameraDisabled = getCameraDisabled(null, policy.mUserHandle);
- if (cameraDisabled != systemState) {
- long token = Binder.clearCallingIdentity();
- try {
- String value = cameraDisabled ? "1" : "0";
- if (DBG) Slog.v(TAG, "Change in camera state ["
- + SYSTEM_PROP_DISABLE_CAMERA + "] = " + value);
- SystemProperties.set(SYSTEM_PROP_DISABLE_CAMERA, value);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- }
-
- public void systemReady() {
- if (!mHasFeature) {
- return;
- }
- synchronized (this) {
- loadSettingsLocked(getUserData(UserHandle.USER_OWNER), UserHandle.USER_OWNER);
- loadDeviceOwner();
- }
- }
-
- private void handlePasswordExpirationNotification(DevicePolicyData policy) {
- synchronized (this) {
- final long now = System.currentTimeMillis();
- final int N = policy.mAdminList.size();
- if (N <= 0) {
- return;
- }
- for (int i=0; i < N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)
- && admin.passwordExpirationTimeout > 0L
- && admin.passwordExpirationDate > 0L
- && now >= admin.passwordExpirationDate - EXPIRATION_GRACE_PERIOD_MS) {
- sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING);
- }
- }
- setExpirationAlarmCheckLocked(mContext, policy);
- }
- }
-
- private void manageMonitoringCertificateNotification(Intent intent) {
- final NotificationManager notificationManager = getNotificationManager();
-
- final boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
- if (! hasCert) {
- if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
- UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- for (UserInfo user : um.getUsers()) {
- notificationManager.cancelAsUser(
- null, MONITORING_CERT_NOTIFICATION_ID, user.getUserHandle());
- }
- }
- return;
- }
- final boolean isManaged = getDeviceOwner() != null;
- int smallIconId;
- String contentText;
- if (isManaged) {
- contentText = mContext.getString(R.string.ssl_ca_cert_noti_managed,
- getDeviceOwnerName());
- smallIconId = R.drawable.stat_sys_certificate_info;
- } else {
- contentText = mContext.getString(R.string.ssl_ca_cert_noti_by_unknown);
- smallIconId = android.R.drawable.stat_sys_warning;
- }
-
- Intent dialogIntent = new Intent(Settings.ACTION_MONITORING_CERT_INFO);
- dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- dialogIntent.setPackage("com.android.settings");
- // Notification will be sent individually to all users. The activity should start as
- // whichever user is current when it starts.
- PendingIntent notifyIntent = PendingIntent.getActivityAsUser(mContext, 0, dialogIntent,
- PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT);
-
- Notification noti = new Notification.Builder(mContext)
- .setSmallIcon(smallIconId)
- .setContentTitle(mContext.getString(R.string.ssl_ca_cert_warning))
- .setContentText(contentText)
- .setContentIntent(notifyIntent)
- .setPriority(Notification.PRIORITY_HIGH)
- .setShowWhen(false)
- .build();
-
- // If this is a boot intent, this will fire for each user. But if this is a storage changed
- // intent, it will fire once, so we need to notify all users.
- if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
- UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- for (UserInfo user : um.getUsers()) {
- notificationManager.notifyAsUser(
- null, MONITORING_CERT_NOTIFICATION_ID, noti, user.getUserHandle());
- }
- } else {
- notificationManager.notifyAsUser(
- null, MONITORING_CERT_NOTIFICATION_ID, noti, UserHandle.CURRENT);
- }
- }
-
- /**
- * @param adminReceiver The admin to add
- * @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);
-
- DevicePolicyData policy = getUserData(userHandle);
- DeviceAdminInfo info = findAdmin(adminReceiver, userHandle);
- if (info == null) {
- throw new IllegalArgumentException("Bad admin: " + adminReceiver);
- }
- synchronized (this) {
- long ident = Binder.clearCallingIdentity();
- try {
- if (!refreshing && getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null) {
- throw new IllegalArgumentException("Admin is already added");
- }
- ActiveAdmin newAdmin = new ActiveAdmin(info);
- policy.mAdminMap.put(adminReceiver, newAdmin);
- int replaceIndex = -1;
- if (refreshing) {
- final int N = policy.mAdminList.size();
- for (int i=0; i < N; i++) {
- ActiveAdmin oldAdmin = policy.mAdminList.get(i);
- if (oldAdmin.info.getComponent().equals(adminReceiver)) {
- replaceIndex = i;
- break;
- }
- }
- }
- if (replaceIndex == -1) {
- policy.mAdminList.add(newAdmin);
- enableIfNecessary(info.getPackageName(), userHandle);
- } else {
- policy.mAdminList.set(replaceIndex, newAdmin);
- }
- saveSettingsLocked(userHandle);
- sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- 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);
- if (administrator == null) {
- throw new SecurityException("No active admin " + adminReceiver);
- }
- return administrator.info.usesPolicy(policyId);
- }
- }
-
- @SuppressWarnings("unchecked")
- public List<ComponentName> getActiveAdmins(int userHandle) {
- if (!mHasFeature) {
- return Collections.EMPTY_LIST;
- }
-
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- if (N <= 0) {
- return null;
- }
- ArrayList<ComponentName> res = new ArrayList<ComponentName>(N);
- for (int i=0; i<N; i++) {
- res.add(policy.mAdminList.get(i).info.getComponent());
- }
- return res;
- }
- }
-
- public boolean packageHasActiveAdmins(String packageName, int userHandle) {
- if (!mHasFeature) {
- return false;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- if (policy.mAdminList.get(i).info.getPackageName().equals(packageName)) {
- return true;
- }
- }
- return false;
- }
- }
-
- public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
- if (admin == null) {
- return;
- }
- if (admin.getUid() != Binder.getCallingUid()) {
- // If trying to remove device owner, refuse when the caller is not the owner.
- if (mDeviceOwner != null
- && adminReceiver.getPackageName().equals(mDeviceOwner.getPackageName())) {
- return;
- }
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
- }
- long ident = Binder.clearCallingIdentity();
- try {
- removeActiveAdminLocked(adminReceiver, userHandle);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- public void setPasswordQuality(ComponentName who, int quality, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- validateQualityConstant(quality);
- enforceCrossUserPermission(userHandle);
-
- synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- if (ap.passwordQuality != quality) {
- ap.passwordQuality = quality;
- saveSettingsLocked(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;
- DevicePolicyData policy = getUserData(userHandle);
-
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.passwordQuality : mode;
- }
-
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (mode < admin.passwordQuality) {
- mode = admin.passwordQuality;
- }
- }
- return mode;
- }
- }
-
- public void setPasswordMinimumLength(ComponentName who, int length, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- if (ap.minimumPasswordLength != length) {
- ap.minimumPasswordLength = length;
- saveSettingsLocked(userHandle);
- }
- }
- }
-
- public int getPasswordMinimumLength(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return 0;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- DevicePolicyData policy = getUserData(userHandle);
- int length = 0;
-
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.minimumPasswordLength : length;
- }
-
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (length < admin.minimumPasswordLength) {
- length = admin.minimumPasswordLength;
- }
- }
- return length;
- }
- }
-
- public void setPasswordHistoryLength(ComponentName who, int length, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- if (ap.passwordHistoryLength != length) {
- ap.passwordHistoryLength = length;
- saveSettingsLocked(userHandle);
- }
- }
- }
-
- public int getPasswordHistoryLength(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return 0;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- DevicePolicyData policy = getUserData(userHandle);
- int length = 0;
-
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.passwordHistoryLength : length;
- }
-
- final int N = policy.mAdminList.size();
- for (int i = 0; i < N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (length < admin.passwordHistoryLength) {
- length = admin.passwordHistoryLength;
- }
- }
- return length;
- }
- }
-
- public void setPasswordExpirationTimeout(ComponentName who, long timeout, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- if (timeout < 0) {
- throw new IllegalArgumentException("Timeout must be >= 0 ms");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD);
- // Calling this API automatically bumps the expiration date
- final long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
- ap.passwordExpirationDate = expiration;
- ap.passwordExpirationTimeout = timeout;
- if (timeout > 0L) {
- Slog.w(TAG, "setPasswordExpiration(): password will expire on "
- + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT)
- .format(new Date(expiration)));
- }
- saveSettingsLocked(userHandle);
- // in case this is the first one
- setExpirationAlarmCheckLocked(mContext, getUserData(userHandle));
- }
- }
-
- /**
- * Return a single admin's expiration cycle time, or the min of all cycle times.
- * Returns 0 if not configured.
- */
- public long getPasswordExpirationTimeout(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return 0L;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.passwordExpirationTimeout : 0L;
- }
-
- long timeout = 0L;
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- for (int i = 0; i < N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (timeout == 0L || (admin.passwordExpirationTimeout != 0L
- && timeout > admin.passwordExpirationTimeout)) {
- timeout = admin.passwordExpirationTimeout;
- }
- }
- return timeout;
- }
- }
-
- /**
- * Return a single admin's expiration date/time, or the min (soonest) for all admins.
- * Returns 0 if not configured.
- */
- private long getPasswordExpirationLocked(ComponentName who, int userHandle) {
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.passwordExpirationDate : 0L;
- }
-
- long timeout = 0L;
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- for (int i = 0; i < N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (timeout == 0L || (admin.passwordExpirationDate != 0
- && timeout > admin.passwordExpirationDate)) {
- timeout = admin.passwordExpirationDate;
- }
- }
- return timeout;
- }
-
- 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) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- if (ap.minimumPasswordUpperCase != length) {
- ap.minimumPasswordUpperCase = length;
- saveSettingsLocked(userHandle);
- }
- }
- }
-
- public int getPasswordMinimumUpperCase(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return 0;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- int length = 0;
-
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.minimumPasswordUpperCase : length;
- }
-
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (length < admin.minimumPasswordUpperCase) {
- length = admin.minimumPasswordUpperCase;
- }
- }
- return length;
- }
- }
-
- public void setPasswordMinimumLowerCase(ComponentName who, int length, int userHandle) {
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- if (ap.minimumPasswordLowerCase != length) {
- ap.minimumPasswordLowerCase = length;
- saveSettingsLocked(userHandle);
- }
- }
- }
-
- public int getPasswordMinimumLowerCase(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return 0;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- int length = 0;
-
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.minimumPasswordLowerCase : length;
- }
-
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (length < admin.minimumPasswordLowerCase) {
- length = admin.minimumPasswordLowerCase;
- }
- }
- return length;
- }
- }
-
- public void setPasswordMinimumLetters(ComponentName who, int length, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- if (ap.minimumPasswordLetters != length) {
- ap.minimumPasswordLetters = length;
- saveSettingsLocked(userHandle);
- }
- }
- }
-
- public int getPasswordMinimumLetters(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return 0;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- int length = 0;
-
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.minimumPasswordLetters : length;
- }
-
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (length < admin.minimumPasswordLetters) {
- length = admin.minimumPasswordLetters;
- }
- }
- return length;
- }
- }
-
- public void setPasswordMinimumNumeric(ComponentName who, int length, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- if (ap.minimumPasswordNumeric != length) {
- ap.minimumPasswordNumeric = length;
- saveSettingsLocked(userHandle);
- }
- }
- }
-
- public int getPasswordMinimumNumeric(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return 0;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- int length = 0;
-
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.minimumPasswordNumeric : length;
- }
-
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- for (int i = 0; i < N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (length < admin.minimumPasswordNumeric) {
- length = admin.minimumPasswordNumeric;
- }
- }
- return length;
- }
- }
-
- public void setPasswordMinimumSymbols(ComponentName who, int length, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- if (ap.minimumPasswordSymbols != length) {
- ap.minimumPasswordSymbols = length;
- saveSettingsLocked(userHandle);
- }
- }
- }
-
- public int getPasswordMinimumSymbols(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return 0;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- int length = 0;
-
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.minimumPasswordSymbols : length;
- }
-
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (length < admin.minimumPasswordSymbols) {
- length = admin.minimumPasswordSymbols;
- }
- }
- return length;
- }
- }
-
- public void setPasswordMinimumNonLetter(ComponentName who, int length, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- if (ap.minimumPasswordNonLetter != length) {
- ap.minimumPasswordNonLetter = length;
- saveSettingsLocked(userHandle);
- }
- }
- }
-
- public int getPasswordMinimumNonLetter(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return 0;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- int length = 0;
-
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.minimumPasswordNonLetter : length;
- }
-
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (length < admin.minimumPasswordNonLetter) {
- length = admin.minimumPasswordNonLetter;
- }
- }
- return length;
- }
- }
-
- public boolean isActivePasswordSufficient(int userHandle) {
- if (!mHasFeature) {
- return true;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- DevicePolicyData policy = getUserData(userHandle);
- // This API can only be called by an active device admin,
- // so try to retrieve it to check that the caller is one.
- getActiveAdminForCallerLocked(null,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
- if (policy.mActivePasswordQuality < getPasswordQuality(null, userHandle)
- || policy.mActivePasswordLength < getPasswordMinimumLength(null, userHandle)) {
- return false;
- }
- if (policy.mActivePasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
- return true;
- }
- return policy.mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null, userHandle)
- && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null, userHandle)
- && policy.mActivePasswordLetters >= getPasswordMinimumLetters(null, userHandle)
- && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(null, userHandle)
- && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(null, userHandle)
- && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null, userHandle);
- }
- }
-
- public int getCurrentFailedPasswordAttempts(int userHandle) {
- enforceCrossUserPermission(userHandle);
- 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.
- getActiveAdminForCallerLocked(null,
- DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
- return getUserData(userHandle).mFailedPasswordAttempts;
- }
- }
-
- 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,
- // so try to retrieve it to check that the caller is one.
- getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_WIPE_DATA);
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
- if (ap.maximumFailedPasswordsForWipe != num) {
- ap.maximumFailedPasswordsForWipe = num;
- saveSettingsLocked(userHandle);
- }
- }
- }
-
- public int getMaximumFailedPasswordsForWipe(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return 0;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- DevicePolicyData policy = getUserData(userHandle);
- int count = 0;
-
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.maximumFailedPasswordsForWipe : count;
- }
-
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (count == 0) {
- count = admin.maximumFailedPasswordsForWipe;
- } else if (admin.maximumFailedPasswordsForWipe != 0
- && count > admin.maximumFailedPasswordsForWipe) {
- count = admin.maximumFailedPasswordsForWipe;
- }
- }
- return count;
- }
- }
-
- public boolean resetPassword(String password, int flags, int userHandle) {
- if (!mHasFeature) {
- return false;
- }
- enforceCrossUserPermission(userHandle);
- int quality;
- 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.
- getActiveAdminForCallerLocked(null,
- DeviceAdminInfo.USES_POLICY_RESET_PASSWORD);
- quality = getPasswordQuality(null, userHandle);
- if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
- int realQuality = LockPatternUtils.computePasswordQuality(password);
- if (realQuality < quality
- && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
- Slog.w(TAG, "resetPassword: password quality 0x"
- + Integer.toHexString(realQuality)
- + " does not meet required quality 0x"
- + Integer.toHexString(quality));
- return false;
- }
- quality = Math.max(realQuality, quality);
- }
- int length = getPasswordMinimumLength(null, userHandle);
- if (password.length() < length) {
- Slog.w(TAG, "resetPassword: password length " + password.length()
- + " does not meet required length " + length);
- return false;
- }
- if (quality == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
- int letters = 0;
- int uppercase = 0;
- int lowercase = 0;
- int numbers = 0;
- int symbols = 0;
- int nonletter = 0;
- for (int i = 0; i < password.length(); i++) {
- char c = password.charAt(i);
- if (c >= 'A' && c <= 'Z') {
- letters++;
- uppercase++;
- } else if (c >= 'a' && c <= 'z') {
- letters++;
- lowercase++;
- } else if (c >= '0' && c <= '9') {
- numbers++;
- nonletter++;
- } else {
- symbols++;
- nonletter++;
- }
- }
- int neededLetters = getPasswordMinimumLetters(null, userHandle);
- if(letters < neededLetters) {
- Slog.w(TAG, "resetPassword: number of letters " + letters
- + " does not meet required number of letters " + neededLetters);
- return false;
- }
- int neededNumbers = getPasswordMinimumNumeric(null, userHandle);
- if (numbers < neededNumbers) {
- Slog.w(TAG, "resetPassword: number of numerical digits " + numbers
- + " does not meet required number of numerical digits "
- + neededNumbers);
- return false;
- }
- int neededLowerCase = getPasswordMinimumLowerCase(null, userHandle);
- if (lowercase < neededLowerCase) {
- Slog.w(TAG, "resetPassword: number of lowercase letters " + lowercase
- + " does not meet required number of lowercase letters "
- + neededLowerCase);
- return false;
- }
- int neededUpperCase = getPasswordMinimumUpperCase(null, userHandle);
- if (uppercase < neededUpperCase) {
- Slog.w(TAG, "resetPassword: number of uppercase letters " + uppercase
- + " does not meet required number of uppercase letters "
- + neededUpperCase);
- return false;
- }
- int neededSymbols = getPasswordMinimumSymbols(null, userHandle);
- if (symbols < neededSymbols) {
- Slog.w(TAG, "resetPassword: number of special symbols " + symbols
- + " does not meet required number of special symbols " + neededSymbols);
- return false;
- }
- int neededNonLetter = getPasswordMinimumNonLetter(null, userHandle);
- if (nonletter < neededNonLetter) {
- Slog.w(TAG, "resetPassword: number of non-letter characters " + nonletter
- + " does not meet required number of non-letter characters "
- + neededNonLetter);
- return false;
- }
- }
- }
-
- int callingUid = Binder.getCallingUid();
- DevicePolicyData policy = getUserData(userHandle);
- if (policy.mPasswordOwner >= 0 && policy.mPasswordOwner != callingUid) {
- Slog.w(TAG, "resetPassword: already set by another uid and not entered by user");
- return false;
- }
-
- // Don't do this with the lock held, because it is going to call
- // back in to the service.
- long ident = Binder.clearCallingIdentity();
- try {
- LockPatternUtils utils = new LockPatternUtils(mContext);
- utils.saveLockPassword(password, quality, false, userHandle);
- synchronized (this) {
- int newOwner = (flags&DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY)
- != 0 ? callingUid : -1;
- if (policy.mPasswordOwner != newOwner) {
- policy.mPasswordOwner = newOwner;
- saveSettingsLocked(userHandle);
- }
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
-
- return true;
- }
-
- public void setMaximumTimeToLock(ComponentName who, long timeMs, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
- if (ap.maximumTimeToUnlock != timeMs) {
- ap.maximumTimeToUnlock = timeMs;
- saveSettingsLocked(userHandle);
- updateMaximumTimeToLockLocked(getUserData(userHandle));
- }
- }
- }
-
- void updateMaximumTimeToLockLocked(DevicePolicyData policy) {
- long timeMs = getMaximumTimeToLock(null, policy.mUserHandle);
- if (policy.mLastMaximumTimeToLock == timeMs) {
- return;
- }
-
- long ident = Binder.clearCallingIdentity();
- try {
- if (timeMs <= 0) {
- timeMs = Integer.MAX_VALUE;
- } else {
- // Make sure KEEP_SCREEN_ON is disabled, since that
- // would allow bypassing of the maximum time to lock.
- Settings.Global.putInt(mContext.getContentResolver(),
- Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
- }
-
- policy.mLastMaximumTimeToLock = timeMs;
-
- try {
- getIPowerManager().setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs);
- } catch (RemoteException e) {
- Slog.w(TAG, "Failure talking with power manager", e);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- public long getMaximumTimeToLock(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return 0;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- long time = 0;
-
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return admin != null ? admin.maximumTimeToUnlock : time;
- }
-
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (time == 0) {
- time = admin.maximumTimeToUnlock;
- } else if (admin.maximumTimeToUnlock != 0
- && time > admin.maximumTimeToUnlock) {
- time = admin.maximumTimeToUnlock;
- }
- }
- return time;
- }
- }
-
- 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.
- getActiveAdminForCallerLocked(null,
- DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
- lockNowUnchecked();
- }
- }
-
- private void lockNowUnchecked() {
- long ident = Binder.clearCallingIdentity();
- try {
- // Power off the display
- getIPowerManager().goToSleep(SystemClock.uptimeMillis(),
- PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN);
- // Ensure the device is locked
- getWindowManager().lockNow(null);
- } catch (RemoteException e) {
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
-
- private boolean isExtStorageEncrypted() {
- String state = SystemProperties.get("vold.decrypt");
- return !"".equals(state);
- }
-
- public boolean installCaCert(byte[] certBuffer) throws RemoteException {
- mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
- KeyChainConnection keyChainConnection = null;
- byte[] pemCert;
- try {
- X509Certificate cert = parseCert(certBuffer);
- pemCert = Credentials.convertToPem(cert);
- } catch (CertificateException ce) {
- Log.e(TAG, "Problem converting cert", ce);
- return false;
- } catch (IOException ioe) {
- Log.e(TAG, "Problem reading cert", ioe);
- return false;
- }
- try {
- keyChainConnection = KeyChain.bind(mContext);
- try {
- keyChainConnection.getService().installCaCertificate(pemCert);
- return true;
- } finally {
- if (keyChainConnection != null) {
- keyChainConnection.close();
- keyChainConnection = null;
- }
- }
- } catch (InterruptedException e1) {
- Log.w(TAG, "installCaCertsToKeyChain(): ", e1);
- Thread.currentThread().interrupt();
- }
- return false;
- }
-
- private static X509Certificate parseCert(byte[] certBuffer)
- throws CertificateException, IOException {
- CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
- return (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(
- certBuffer));
- }
-
- public void uninstallCaCert(final byte[] certBuffer) {
- mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
- TrustedCertificateStore certStore = new TrustedCertificateStore();
- String alias = null;
- try {
- X509Certificate cert = parseCert(certBuffer);
- alias = certStore.getCertificateAlias(cert);
- } catch (CertificateException ce) {
- Log.e(TAG, "Problem creating X509Certificate", ce);
- return;
- } catch (IOException ioe) {
- Log.e(TAG, "Problem reading certificate", ioe);
- return;
- }
- try {
- KeyChainConnection keyChainConnection = KeyChain.bind(mContext);
- IKeyChainService service = keyChainConnection.getService();
- try {
- service.deleteCaCertificate(alias);
- } catch (RemoteException e) {
- Log.e(TAG, "from CaCertUninstaller: ", e);
- } finally {
- keyChainConnection.close();
- keyChainConnection = null;
- }
- } catch (InterruptedException ie) {
- Log.w(TAG, "CaCertUninstaller: ", ie);
- Thread.currentThread().interrupt();
- }
- }
-
- void wipeDataLocked(int flags) {
- // If the SD card is encrypted and non-removable, we have to force a wipe.
- boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
- boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0;
-
- // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
- if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
- Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
- intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true);
- intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
- mWakeLock.acquire(10000);
- mContext.startService(intent);
- } else {
- try {
- RecoverySystem.rebootWipeUserData(mContext);
- } catch (IOException e) {
- Slog.w(TAG, "Failed requesting data wipe", e);
- }
- }
- }
-
- 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,
- // so try to retrieve it to check that the caller is one.
- getActiveAdminForCallerLocked(null,
- DeviceAdminInfo.USES_POLICY_WIPE_DATA);
- long ident = Binder.clearCallingIdentity();
- try {
- wipeDeviceOrUserLocked(flags, userHandle);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- private void wipeDeviceOrUserLocked(int flags, final int userHandle) {
- if (userHandle == UserHandle.USER_OWNER) {
- wipeDataLocked(flags);
- } else {
- lockNowUnchecked();
- mHandler.post(new Runnable() {
- public void run() {
- try {
- ActivityManagerNative.getDefault().switchUser(UserHandle.USER_OWNER);
- ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
- .removeUser(userHandle);
- } catch (RemoteException re) {
- // Shouldn't happen
- }
- }
- });
- }
- }
-
- public void getRemoveWarning(ComponentName comp, final RemoteCallback result, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- enforceCrossUserPermission(userHandle);
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.BIND_DEVICE_ADMIN, null);
-
- synchronized (this) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(comp, userHandle);
- if (admin == null) {
- try {
- result.sendResult(null);
- } catch (RemoteException e) {
- }
- return;
- }
- Intent intent = new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED);
- intent.setComponent(admin.info.getComponent());
- mContext.sendOrderedBroadcastAsUser(intent, new UserHandle(userHandle),
- null, new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- try {
- result.sendResult(getResultExtras(false));
- } catch (RemoteException e) {
- }
- }
- }, null, Activity.RESULT_OK, null, 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);
- DevicePolicyData p = getUserData(userHandle);
-
- validateQualityConstant(quality);
-
- synchronized (this) {
- if (p.mActivePasswordQuality != quality || p.mActivePasswordLength != length
- || p.mFailedPasswordAttempts != 0 || p.mActivePasswordLetters != letters
- || p.mActivePasswordUpperCase != uppercase
- || p.mActivePasswordLowerCase != lowercase || p.mActivePasswordNumeric != numbers
- || p.mActivePasswordSymbols != symbols || p.mActivePasswordNonLetter != nonletter) {
- long ident = Binder.clearCallingIdentity();
- try {
- p.mActivePasswordQuality = quality;
- p.mActivePasswordLength = length;
- p.mActivePasswordLetters = letters;
- p.mActivePasswordLowerCase = lowercase;
- p.mActivePasswordUpperCase = uppercase;
- p.mActivePasswordNumeric = numbers;
- p.mActivePasswordSymbols = symbols;
- p.mActivePasswordNonLetter = nonletter;
- p.mFailedPasswordAttempts = 0;
- saveSettingsLocked(userHandle);
- updatePasswordExpirationsLocked(userHandle);
- setExpirationAlarmCheckLocked(mContext, p);
- sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
- DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle);
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
- }
-
- /**
- * Called any time the device password is updated. Resets all password expiration clocks.
- */
- private void updatePasswordExpirationsLocked(int userHandle) {
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- if (N > 0) {
- for (int i=0; i<N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) {
- long timeout = admin.passwordExpirationTimeout;
- long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
- admin.passwordExpirationDate = expiration;
- }
- }
- saveSettingsLocked(userHandle);
- }
- }
-
- public void reportFailedPasswordAttempt(int userHandle) {
- enforceCrossUserPermission(userHandle);
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.BIND_DEVICE_ADMIN, null);
-
- synchronized (this) {
- DevicePolicyData policy = getUserData(userHandle);
- long ident = Binder.clearCallingIdentity();
- try {
- policy.mFailedPasswordAttempts++;
- saveSettingsLocked(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);
- }
- } finally {
- Binder.restoreCallingIdentity(ident);
- }
- }
- }
-
- public void reportSuccessfulPasswordAttempt(int userHandle) {
- enforceCrossUserPermission(userHandle);
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.BIND_DEVICE_ADMIN, null);
-
- synchronized (this) {
- DevicePolicyData policy = getUserData(userHandle);
- if (policy.mFailedPasswordAttempts != 0 || policy.mPasswordOwner >= 0) {
- long ident = Binder.clearCallingIdentity();
- try {
- policy.mFailedPasswordAttempts = 0;
- policy.mPasswordOwner = -1;
- saveSettingsLocked(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) {
- throw new NullPointerException("ComponentName is null");
- }
-
- // Only check if owner has set global proxy. We don't allow other users to set it.
- DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
- ActiveAdmin admin = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
-
- // Scan through active admins and find if anyone has already
- // set the global proxy.
- Set<ComponentName> compSet = policy.mAdminMap.keySet();
- for (ComponentName component : compSet) {
- ActiveAdmin ap = policy.mAdminMap.get(component);
- if ((ap.specifiesGlobalProxy) && (!component.equals(who))) {
- // Another admin already sets the global proxy
- // Return it to the caller.
- return component;
- }
- }
-
- // If the user is not the owner, don't set the global proxy. Fail silently.
- if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
- Slog.w(TAG, "Only the owner is allowed to set the global proxy. User "
- + userHandle + " is not permitted.");
- return null;
- }
- if (proxySpec == null) {
- admin.specifiesGlobalProxy = false;
- admin.globalProxySpec = null;
- admin.globalProxyExclusionList = null;
- } else {
-
- admin.specifiesGlobalProxy = true;
- admin.globalProxySpec = proxySpec;
- admin.globalProxyExclusionList = exclusionList;
- }
-
- // Reset the global proxy accordingly
- // Do this using system permissions, as apps cannot write to secure settings
- long origId = Binder.clearCallingIdentity();
- resetGlobalProxyLocked(policy);
- Binder.restoreCallingIdentity(origId);
- return null;
- }
- }
-
- public ComponentName getGlobalProxyAdmin(int userHandle) {
- if (!mHasFeature) {
- return null;
- }
- enforceCrossUserPermission(userHandle);
- synchronized(this) {
- DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
- // Scan through active admins and find if anyone has already
- // set the global proxy.
- final int N = policy.mAdminList.size();
- for (int i = 0; i < N; i++) {
- ActiveAdmin ap = policy.mAdminList.get(i);
- if (ap.specifiesGlobalProxy) {
- // Device admin sets the global proxy
- // Return it to the caller.
- return ap.info.getComponent();
- }
- }
- }
- // No device admin sets the global proxy.
- return null;
- }
-
- private void resetGlobalProxyLocked(DevicePolicyData policy) {
- final int N = policy.mAdminList.size();
- for (int i = 0; i < N; i++) {
- ActiveAdmin ap = policy.mAdminList.get(i);
- if (ap.specifiesGlobalProxy) {
- saveGlobalProxyLocked(ap.globalProxySpec, ap.globalProxyExclusionList);
- return;
- }
- }
- // No device admins defining global proxies - reset global proxy settings to none
- saveGlobalProxyLocked(null, null);
- }
-
- private void saveGlobalProxyLocked(String proxySpec, String exclusionList) {
- if (exclusionList == null) {
- exclusionList = "";
- }
- if (proxySpec == null) {
- proxySpec = "";
- }
- // Remove white spaces
- proxySpec = proxySpec.trim();
- String data[] = proxySpec.split(":");
- int proxyPort = 8080;
- if (data.length > 1) {
- try {
- proxyPort = Integer.parseInt(data[1]);
- } catch (NumberFormatException e) {}
- }
- exclusionList = exclusionList.trim();
- ContentResolver res = mContext.getContentResolver();
-
- ProxyProperties proxyProperties = new ProxyProperties(data[0], proxyPort, exclusionList);
- if (!proxyProperties.isValid()) {
- Slog.e(TAG, "Invalid proxy properties, ignoring: " + proxyProperties.toString());
- return;
- }
- Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, data[0]);
- Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, proxyPort);
- Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
- exclusionList);
- }
-
- /**
- * Set the storage encryption request for a single admin. Returns the new total request
- * 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
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- // Only owner can set storage encryption
- if (userHandle != UserHandle.USER_OWNER
- || UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
- Slog.w(TAG, "Only owner is allowed to set storage encryption. User "
- + UserHandle.getCallingUserId() + " is not permitted.");
- return 0;
- }
-
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_ENCRYPTED_STORAGE);
-
- // Quick exit: If the filesystem does not support encryption, we can exit early.
- if (!isEncryptionSupported()) {
- return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
- }
-
- // (1) Record the value for the admin so it's sticky
- if (ap.encryptionRequested != encrypt) {
- ap.encryptionRequested = encrypt;
- saveSettingsLocked(userHandle);
- }
-
- DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
- // (2) Compute "max" for all admins
- boolean newRequested = false;
- final int N = policy.mAdminList.size();
- for (int i = 0; i < N; i++) {
- newRequested |= policy.mAdminList.get(i).encryptionRequested;
- }
-
- // Notify OS of new request
- setEncryptionRequested(newRequested);
-
- // Return the new global request status
- return newRequested
- ? DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE
- : DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
- }
- }
-
- /**
- * Get the current storage encryption request status for a given admin, or aggregate of all
- * 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
- if (who != null) {
- // When checking for a single caller, status is based on caller's request
- ActiveAdmin ap = getActiveAdminUncheckedLocked(who, userHandle);
- return ap != null ? ap.encryptionRequested : false;
- }
-
- // If no particular caller is specified, return the aggregate set of requests.
- // This is short circuited by returning true on the first hit.
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- for (int i = 0; i < N; i++) {
- if (policy.mAdminList.get(i).encryptionRequested) {
- return true;
- }
- }
- return false;
- }
- }
-
- /**
- * Get the current encryption status of the device.
- */
- public int getStorageEncryptionStatus(int userHandle) {
- if (!mHasFeature) {
- // Ok to return current status.
- }
- enforceCrossUserPermission(userHandle);
- return getEncryptionStatus();
- }
-
- /**
- * Hook to low-levels: This should report if the filesystem supports encrypted storage.
- */
- private boolean isEncryptionSupported() {
- // Note, this can be implemented as
- // return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
- // But is provided as a separate internal method if there's a faster way to do a
- // simple check for supported-or-not.
- return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
- }
-
- /**
- * Hook to low-levels: Reporting the current status of encryption.
- * @return A value such as {@link DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED} or
- * {@link DevicePolicyManager#ENCRYPTION_STATUS_INACTIVE} or
- * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE}.
- */
- private int getEncryptionStatus() {
- String status = SystemProperties.get("ro.crypto.state", "unsupported");
- if ("encrypted".equalsIgnoreCase(status)) {
- return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
- } else if ("unencrypted".equalsIgnoreCase(status)) {
- return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
- } else {
- return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
- }
- }
-
- /**
- * Hook to low-levels: If needed, record the new admin setting for encryption.
- */
- private void setEncryptionRequested(boolean encrypt) {
- }
-
- /**
- * The system property used to share the state of the camera. The native camera service
- * is expected to read this property and act accordingly.
- */
- public static final String SYSTEM_PROP_DISABLE_CAMERA = "sys.secpolicy.camera.disabled";
-
- /**
- * 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) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA);
- if (ap.disableCamera != disabled) {
- ap.disableCamera = disabled;
- saveSettingsLocked(userHandle);
- }
- syncDeviceCapabilitiesLocked(getUserData(userHandle));
- }
- }
-
- /**
- * Gets whether or not all device cameras are disabled for a given admin, or disabled for any
- * active admins.
- */
- public boolean getCameraDisabled(ComponentName who, int userHandle) {
- if (!mHasFeature) {
- return false;
- }
- synchronized (this) {
- if (who != null) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return (admin != null) ? admin.disableCamera : false;
- }
-
- DevicePolicyData policy = getUserData(userHandle);
- // Determine whether or not the device camera is disabled for any active admins.
- final int N = policy.mAdminList.size();
- for (int i = 0; i < N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- if (admin.disableCamera) {
- return true;
- }
- }
- return false;
- }
- }
-
- /**
- * Selectively disable keyguard features.
- */
- public void setKeyguardDisabledFeatures(ComponentName who, int which, int userHandle) {
- if (!mHasFeature) {
- return;
- }
- enforceCrossUserPermission(userHandle);
- synchronized (this) {
- if (who == null) {
- throw new NullPointerException("ComponentName is null");
- }
- ActiveAdmin ap = getActiveAdminForCallerLocked(who,
- DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
- if (ap.disabledKeyguardFeatures != which) {
- ap.disabledKeyguardFeatures = which;
- saveSettingsLocked(userHandle);
- }
- syncDeviceCapabilitiesLocked(getUserData(userHandle));
- }
- }
-
- /**
- * Gets the disabled state for features in keyguard for the given admin,
- * 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) {
- ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
- return (admin != null) ? admin.disabledKeyguardFeatures : 0;
- }
-
- // Determine which keyguard features are disabled for any active admins.
- DevicePolicyData policy = getUserData(userHandle);
- final int N = policy.mAdminList.size();
- int which = 0;
- for (int i = 0; i < N; i++) {
- ActiveAdmin admin = policy.mAdminList.get(i);
- which |= admin.disabledKeyguardFeatures;
- }
- return which;
- }
- }
-
- @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
- + " for device owner");
- }
- synchronized (this) {
- if (mDeviceOwner == null && !isDeviceProvisioned()) {
- mDeviceOwner = new DeviceOwner(packageName, ownerName);
- mDeviceOwner.writeOwnerFile();
- return true;
- } else {
- throw new IllegalStateException("Trying to set device owner to " + packageName
- + ", owner=" + mDeviceOwner.getPackageName()
- + ", device_provisioned=" + isDeviceProvisioned());
- }
- }
- }
-
- @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();
- }
- }
- return null;
- }
-
- @Override
- public String getDeviceOwnerName() {
- if (!mHasFeature) {
- return null;
- }
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
- synchronized (this) {
- if (mDeviceOwner != null) {
- return mDeviceOwner.getName();
- }
- }
- return null;
- }
-
- private boolean isDeviceProvisioned() {
- return Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.DEVICE_PROVISIONED, 0) > 0;
- }
-
- private void enforceCrossUserPermission(int userHandle) {
- if (userHandle < 0) {
- throw new IllegalArgumentException("Invalid userId " + userHandle);
- }
- final int callingUid = Binder.getCallingUid();
- if (userHandle == UserHandle.getUserId(callingUid)) return;
- if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, "Must be system or have"
- + " INTERACT_ACROSS_USERS_FULL permission");
- }
- }
-
- private void enableIfNecessary(String packageName, int userId) {
- try {
- IPackageManager ipm = AppGlobals.getPackageManager();
- ApplicationInfo ai = ipm.getApplicationInfo(packageName,
- PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
- userId);
- if (ai.enabledSetting
- == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
- ipm.setApplicationEnabledSetting(packageName,
- PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
- PackageManager.DONT_KILL_APP, userId, "DevicePolicyManager");
- }
- } catch (RemoteException e) {
- }
- }
-
- @Override
- protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
- != PackageManager.PERMISSION_GRANTED) {
-
- pw.println("Permission Denial: can't dump DevicePolicyManagerService from from pid="
- + Binder.getCallingPid()
- + ", uid=" + Binder.getCallingUid());
- return;
- }
-
- final Printer p = new PrintWriterPrinter(pw);
-
- synchronized (this) {
- p.println("Current Device Policy Manager state:");
-
- int userCount = mUserData.size();
- for (int u = 0; u < userCount; u++) {
- DevicePolicyData policy = getUserData(mUserData.keyAt(u));
- p.println(" Enabled Device Admins (User " + policy.mUserHandle + "):");
- final int N = policy.mAdminList.size();
- for (int i=0; i<N; i++) {
- ActiveAdmin ap = policy.mAdminList.get(i);
- if (ap != null) {
- pw.print(" "); pw.print(ap.info.getComponent().flattenToShortString());
- pw.println(":");
- ap.dump(" ", pw);
- }
- }
-
- pw.println(" ");
- pw.print(" mPasswordOwner="); pw.println(policy.mPasswordOwner);
- }
- }
- }
-
- static class DeviceOwner {
- private static final String DEVICE_OWNER_XML = "device_owner.xml";
- private static final String TAG_DEVICE_OWNER = "device-owner";
- private static final String ATTR_NAME = "name";
- private static final String ATTR_PACKAGE = "package";
- private String mPackageName;
- private String mOwnerName;
-
- DeviceOwner() {
- readOwnerFile();
- }
-
- DeviceOwner(String packageName, String ownerName) {
- this.mPackageName = packageName;
- this.mOwnerName = ownerName;
- }
-
- static boolean isRegistered() {
- return new File(Environment.getSystemSecureDirectory(),
- DEVICE_OWNER_XML).exists();
- }
-
- String getPackageName() {
- return mPackageName;
- }
-
- String getName() {
- return mOwnerName;
- }
-
- static boolean isInstalled(String packageName, PackageManager pm) {
- try {
- PackageInfo pi;
- if ((pi = pm.getPackageInfo(packageName, 0)) != null) {
- if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- return true;
- }
- }
- } catch (NameNotFoundException nnfe) {
- Slog.w(TAG, "Device Owner package " + packageName + " not installed.");
- }
- return false;
- }
-
- void readOwnerFile() {
- AtomicFile file = new AtomicFile(new File(Environment.getSystemSecureDirectory(),
- DEVICE_OWNER_XML));
- try {
- FileInputStream input = file.openRead();
- XmlPullParser parser = Xml.newPullParser();
- parser.setInput(input, null);
- int type;
- while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
- && type != XmlPullParser.START_TAG) {
- }
- String tag = parser.getName();
- if (!TAG_DEVICE_OWNER.equals(tag)) {
- throw new XmlPullParserException(
- "Device Owner file does not start with device-owner tag: found " + tag);
- }
- mPackageName = parser.getAttributeValue(null, ATTR_PACKAGE);
- mOwnerName = parser.getAttributeValue(null, ATTR_NAME);
- input.close();
- } catch (XmlPullParserException xppe) {
- Slog.e(TAG, "Error parsing device-owner file\n" + xppe);
- } catch (IOException ioe) {
- Slog.e(TAG, "IO Exception when reading device-owner file\n" + ioe);
- }
- }
-
- void writeOwnerFile() {
- synchronized (this) {
- writeOwnerFileLocked();
- }
- }
-
- private void writeOwnerFileLocked() {
- AtomicFile file = new AtomicFile(new File(Environment.getSystemSecureDirectory(),
- DEVICE_OWNER_XML));
- try {
- FileOutputStream output = file.startWrite();
- XmlSerializer out = new FastXmlSerializer();
- out.setOutput(output, "utf-8");
- out.startDocument(null, true);
- out.startTag(null, TAG_DEVICE_OWNER);
- out.attribute(null, ATTR_PACKAGE, mPackageName);
- if (mOwnerName != null) {
- out.attribute(null, ATTR_NAME, mOwnerName);
- }
- out.endTag(null, TAG_DEVICE_OWNER);
- out.endDocument();
- out.flush();
- file.finishWrite(output);
- } catch (IOException ioe) {
- Slog.e(TAG, "IO Exception when writing device-owner file\n" + ioe);
- }
- }
- }
-}