diff options
Diffstat (limited to 'services/java/com/android/server/DevicePolicyManagerService.java')
-rw-r--r-- | services/java/com/android/server/DevicePolicyManagerService.java | 2942 |
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); - } - } - } -} |