Home | History | Annotate | Download | only in server
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server;
     18 
     19 import static android.Manifest.permission.MANAGE_CA_CERTIFICATES;
     20 
     21 import com.android.internal.R;
     22 import com.android.internal.os.storage.ExternalStorageFormatter;
     23 import com.android.internal.util.FastXmlSerializer;
     24 import com.android.internal.util.JournaledFile;
     25 import com.android.internal.util.XmlUtils;
     26 import com.android.internal.widget.LockPatternUtils;
     27 import com.android.org.conscrypt.TrustedCertificateStore;
     28 
     29 import org.xmlpull.v1.XmlPullParser;
     30 import org.xmlpull.v1.XmlPullParserException;
     31 import org.xmlpull.v1.XmlSerializer;
     32 
     33 import android.app.Activity;
     34 import android.app.ActivityManagerNative;
     35 import android.app.AlarmManager;
     36 import android.app.AppGlobals;
     37 import android.app.INotificationManager;
     38 import android.app.Notification;
     39 import android.app.NotificationManager;
     40 import android.app.PendingIntent;
     41 import android.app.admin.DeviceAdminInfo;
     42 import android.app.admin.DeviceAdminReceiver;
     43 import android.app.admin.DevicePolicyManager;
     44 import android.app.admin.IDevicePolicyManager;
     45 import android.content.BroadcastReceiver;
     46 import android.content.ComponentName;
     47 import android.content.ContentResolver;
     48 import android.content.Context;
     49 import android.content.Intent;
     50 import android.content.IntentFilter;
     51 import android.content.pm.ApplicationInfo;
     52 import android.content.pm.IPackageManager;
     53 import android.content.pm.PackageInfo;
     54 import android.content.pm.PackageManager;
     55 import android.content.pm.Signature;
     56 import android.content.pm.PackageManager.NameNotFoundException;
     57 import android.content.pm.ResolveInfo;
     58 import android.content.pm.UserInfo;
     59 import android.net.ProxyProperties;
     60 import android.net.Uri;
     61 import android.os.AsyncTask;
     62 import android.os.Binder;
     63 import android.os.Bundle;
     64 import android.os.Environment;
     65 import android.os.Handler;
     66 import android.os.IBinder;
     67 import android.os.IPowerManager;
     68 import android.os.PowerManager;
     69 import android.os.Process;
     70 import android.os.RecoverySystem;
     71 import android.os.RemoteCallback;
     72 import android.os.RemoteException;
     73 import android.os.ServiceManager;
     74 import android.os.SystemClock;
     75 import android.os.SystemProperties;
     76 import android.os.UserHandle;
     77 import android.os.UserManager;
     78 import android.provider.Settings;
     79 import android.security.Credentials;
     80 import android.security.IKeyChainService;
     81 import android.security.KeyChain;
     82 import android.security.KeyChain.KeyChainConnection;
     83 import android.util.AtomicFile;
     84 import android.util.Log;
     85 import android.util.PrintWriterPrinter;
     86 import android.util.Printer;
     87 import android.util.Slog;
     88 import android.util.SparseArray;
     89 import android.util.Xml;
     90 import android.view.IWindowManager;
     91 import android.view.WindowManagerPolicy;
     92 
     93 import java.io.ByteArrayInputStream;
     94 import java.io.File;
     95 import java.io.FileDescriptor;
     96 import java.io.FileInputStream;
     97 import java.io.FileNotFoundException;
     98 import java.io.FileOutputStream;
     99 import java.io.IOException;
    100 import java.io.PrintWriter;
    101 import java.security.KeyStore.TrustedCertificateEntry;
    102 import java.security.cert.CertificateException;
    103 import java.security.cert.CertificateFactory;
    104 import java.security.cert.X509Certificate;
    105 import java.text.DateFormat;
    106 import java.util.ArrayList;
    107 import java.util.Arrays;
    108 import java.util.Collection;
    109 import java.util.Collections;
    110 import java.util.Date;
    111 import java.util.HashMap;
    112 import java.util.List;
    113 import java.util.Set;
    114 
    115 /**
    116  * Implementation of the device policy APIs.
    117  */
    118 public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
    119 
    120     private static final String TAG = "DevicePolicyManagerService";
    121 
    122     private static final String DEVICE_POLICIES_XML = "device_policies.xml";
    123 
    124     private static final int REQUEST_EXPIRE_PASSWORD = 5571;
    125 
    126     private static final long MS_PER_DAY = 86400 * 1000;
    127 
    128     private static final long EXPIRATION_GRACE_PERIOD_MS = 5 * MS_PER_DAY; // 5 days, in ms
    129 
    130     protected static final String ACTION_EXPIRED_PASSWORD_NOTIFICATION
    131             = "com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION";
    132 
    133     private static final int MONITORING_CERT_NOTIFICATION_ID = R.string.ssl_ca_cert_warning;
    134 
    135     private static final boolean DBG = false;
    136 
    137     final Context mContext;
    138     final PowerManager.WakeLock mWakeLock;
    139 
    140     IPowerManager mIPowerManager;
    141     IWindowManager mIWindowManager;
    142     NotificationManager mNotificationManager;
    143 
    144     private DeviceOwner mDeviceOwner;
    145 
    146     /**
    147      * Whether or not device admin feature is supported. If it isn't return defaults for all
    148      * public methods.
    149      */
    150     private boolean mHasFeature;
    151 
    152     public static class DevicePolicyData {
    153         int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
    154         int mActivePasswordLength = 0;
    155         int mActivePasswordUpperCase = 0;
    156         int mActivePasswordLowerCase = 0;
    157         int mActivePasswordLetters = 0;
    158         int mActivePasswordNumeric = 0;
    159         int mActivePasswordSymbols = 0;
    160         int mActivePasswordNonLetter = 0;
    161         int mFailedPasswordAttempts = 0;
    162 
    163         int mUserHandle;;
    164         int mPasswordOwner = -1;
    165         long mLastMaximumTimeToLock = -1;
    166 
    167         final HashMap<ComponentName, ActiveAdmin> mAdminMap
    168                 = new HashMap<ComponentName, ActiveAdmin>();
    169         final ArrayList<ActiveAdmin> mAdminList
    170                 = new ArrayList<ActiveAdmin>();
    171 
    172         public DevicePolicyData(int userHandle) {
    173             mUserHandle = userHandle;
    174         }
    175     }
    176 
    177     final SparseArray<DevicePolicyData> mUserData = new SparseArray<DevicePolicyData>();
    178 
    179     Handler mHandler = new Handler();
    180 
    181     BroadcastReceiver mReceiver = new BroadcastReceiver() {
    182         @Override
    183         public void onReceive(Context context, Intent intent) {
    184             final String action = intent.getAction();
    185             final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE,
    186                     getSendingUserId());
    187             if (Intent.ACTION_BOOT_COMPLETED.equals(action)
    188                     || ACTION_EXPIRED_PASSWORD_NOTIFICATION.equals(action)) {
    189                 if (DBG) Slog.v(TAG, "Sending password expiration notifications for action "
    190                         + action + " for user " + userHandle);
    191                 mHandler.post(new Runnable() {
    192                     public void run() {
    193                         handlePasswordExpirationNotification(getUserData(userHandle));
    194                     }
    195                 });
    196             }
    197             if (Intent.ACTION_BOOT_COMPLETED.equals(action)
    198                     || KeyChain.ACTION_STORAGE_CHANGED.equals(action)) {
    199                 manageMonitoringCertificateNotification(intent);
    200             }
    201             if (Intent.ACTION_USER_REMOVED.equals(action)) {
    202                 removeUserData(userHandle);
    203             } else if (Intent.ACTION_USER_STARTED.equals(action)
    204                     || Intent.ACTION_PACKAGE_CHANGED.equals(action)
    205                     || Intent.ACTION_PACKAGE_REMOVED.equals(action)
    206                     || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
    207 
    208                 if (Intent.ACTION_USER_STARTED.equals(action)) {
    209                     // Reset the policy data
    210                     synchronized (DevicePolicyManagerService.this) {
    211                         mUserData.remove(userHandle);
    212                     }
    213                 }
    214 
    215                 handlePackagesChanged(userHandle);
    216             }
    217         }
    218     };
    219 
    220     static class ActiveAdmin {
    221         final DeviceAdminInfo info;
    222 
    223         int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
    224 
    225         static final int DEF_MINIMUM_PASSWORD_LENGTH = 0;
    226         int minimumPasswordLength = DEF_MINIMUM_PASSWORD_LENGTH;
    227 
    228         static final int DEF_PASSWORD_HISTORY_LENGTH = 0;
    229         int passwordHistoryLength = DEF_PASSWORD_HISTORY_LENGTH;
    230 
    231         static final int DEF_MINIMUM_PASSWORD_UPPER_CASE = 0;
    232         int minimumPasswordUpperCase = DEF_MINIMUM_PASSWORD_UPPER_CASE;
    233 
    234         static final int DEF_MINIMUM_PASSWORD_LOWER_CASE = 0;
    235         int minimumPasswordLowerCase = DEF_MINIMUM_PASSWORD_LOWER_CASE;
    236 
    237         static final int DEF_MINIMUM_PASSWORD_LETTERS = 1;
    238         int minimumPasswordLetters = DEF_MINIMUM_PASSWORD_LETTERS;
    239 
    240         static final int DEF_MINIMUM_PASSWORD_NUMERIC = 1;
    241         int minimumPasswordNumeric = DEF_MINIMUM_PASSWORD_NUMERIC;
    242 
    243         static final int DEF_MINIMUM_PASSWORD_SYMBOLS = 1;
    244         int minimumPasswordSymbols = DEF_MINIMUM_PASSWORD_SYMBOLS;
    245 
    246         static final int DEF_MINIMUM_PASSWORD_NON_LETTER = 0;
    247         int minimumPasswordNonLetter = DEF_MINIMUM_PASSWORD_NON_LETTER;
    248 
    249         static final long DEF_MAXIMUM_TIME_TO_UNLOCK = 0;
    250         long maximumTimeToUnlock = DEF_MAXIMUM_TIME_TO_UNLOCK;
    251 
    252         static final int DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE = 0;
    253         int maximumFailedPasswordsForWipe = DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE;
    254 
    255         static final long DEF_PASSWORD_EXPIRATION_TIMEOUT = 0;
    256         long passwordExpirationTimeout = DEF_PASSWORD_EXPIRATION_TIMEOUT;
    257 
    258         static final long DEF_PASSWORD_EXPIRATION_DATE = 0;
    259         long passwordExpirationDate = DEF_PASSWORD_EXPIRATION_DATE;
    260 
    261         static final int DEF_KEYGUARD_FEATURES_DISABLED = 0; // none
    262         int disabledKeyguardFeatures = DEF_KEYGUARD_FEATURES_DISABLED;
    263 
    264         boolean encryptionRequested = false;
    265         boolean disableCamera = false;
    266 
    267         // TODO: review implementation decisions with frameworks team
    268         boolean specifiesGlobalProxy = false;
    269         String globalProxySpec = null;
    270         String globalProxyExclusionList = null;
    271 
    272         ActiveAdmin(DeviceAdminInfo _info) {
    273             info = _info;
    274         }
    275 
    276         int getUid() { return info.getActivityInfo().applicationInfo.uid; }
    277 
    278         public UserHandle getUserHandle() {
    279             return new UserHandle(UserHandle.getUserId(info.getActivityInfo().applicationInfo.uid));
    280         }
    281 
    282         void writeToXml(XmlSerializer out)
    283                 throws IllegalArgumentException, IllegalStateException, IOException {
    284             out.startTag(null, "policies");
    285             info.writePoliciesToXml(out);
    286             out.endTag(null, "policies");
    287             if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
    288                 out.startTag(null, "password-quality");
    289                 out.attribute(null, "value", Integer.toString(passwordQuality));
    290                 out.endTag(null, "password-quality");
    291                 if (minimumPasswordLength != DEF_MINIMUM_PASSWORD_LENGTH) {
    292                     out.startTag(null, "min-password-length");
    293                     out.attribute(null, "value", Integer.toString(minimumPasswordLength));
    294                     out.endTag(null, "min-password-length");
    295                 }
    296                 if(passwordHistoryLength != DEF_PASSWORD_HISTORY_LENGTH) {
    297                     out.startTag(null, "password-history-length");
    298                     out.attribute(null, "value", Integer.toString(passwordHistoryLength));
    299                     out.endTag(null, "password-history-length");
    300                 }
    301                 if (minimumPasswordUpperCase != DEF_MINIMUM_PASSWORD_UPPER_CASE) {
    302                     out.startTag(null, "min-password-uppercase");
    303                     out.attribute(null, "value", Integer.toString(minimumPasswordUpperCase));
    304                     out.endTag(null, "min-password-uppercase");
    305                 }
    306                 if (minimumPasswordLowerCase != DEF_MINIMUM_PASSWORD_LOWER_CASE) {
    307                     out.startTag(null, "min-password-lowercase");
    308                     out.attribute(null, "value", Integer.toString(minimumPasswordLowerCase));
    309                     out.endTag(null, "min-password-lowercase");
    310                 }
    311                 if (minimumPasswordLetters != DEF_MINIMUM_PASSWORD_LETTERS) {
    312                     out.startTag(null, "min-password-letters");
    313                     out.attribute(null, "value", Integer.toString(minimumPasswordLetters));
    314                     out.endTag(null, "min-password-letters");
    315                 }
    316                 if (minimumPasswordNumeric != DEF_MINIMUM_PASSWORD_NUMERIC) {
    317                     out.startTag(null, "min-password-numeric");
    318                     out.attribute(null, "value", Integer.toString(minimumPasswordNumeric));
    319                     out.endTag(null, "min-password-numeric");
    320                 }
    321                 if (minimumPasswordSymbols != DEF_MINIMUM_PASSWORD_SYMBOLS) {
    322                     out.startTag(null, "min-password-symbols");
    323                     out.attribute(null, "value", Integer.toString(minimumPasswordSymbols));
    324                     out.endTag(null, "min-password-symbols");
    325                 }
    326                 if (minimumPasswordNonLetter > DEF_MINIMUM_PASSWORD_NON_LETTER) {
    327                     out.startTag(null, "min-password-nonletter");
    328                     out.attribute(null, "value", Integer.toString(minimumPasswordNonLetter));
    329                     out.endTag(null, "min-password-nonletter");
    330                 }
    331             }
    332             if (maximumTimeToUnlock != DEF_MAXIMUM_TIME_TO_UNLOCK) {
    333                 out.startTag(null, "max-time-to-unlock");
    334                 out.attribute(null, "value", Long.toString(maximumTimeToUnlock));
    335                 out.endTag(null, "max-time-to-unlock");
    336             }
    337             if (maximumFailedPasswordsForWipe != DEF_MAXIMUM_FAILED_PASSWORDS_FOR_WIPE) {
    338                 out.startTag(null, "max-failed-password-wipe");
    339                 out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe));
    340                 out.endTag(null, "max-failed-password-wipe");
    341             }
    342             if (specifiesGlobalProxy) {
    343                 out.startTag(null, "specifies-global-proxy");
    344                 out.attribute(null, "value", Boolean.toString(specifiesGlobalProxy));
    345                 out.endTag(null, "specifies_global_proxy");
    346                 if (globalProxySpec != null) {
    347                     out.startTag(null, "global-proxy-spec");
    348                     out.attribute(null, "value", globalProxySpec);
    349                     out.endTag(null, "global-proxy-spec");
    350                 }
    351                 if (globalProxyExclusionList != null) {
    352                     out.startTag(null, "global-proxy-exclusion-list");
    353                     out.attribute(null, "value", globalProxyExclusionList);
    354                     out.endTag(null, "global-proxy-exclusion-list");
    355                 }
    356             }
    357             if (passwordExpirationTimeout != DEF_PASSWORD_EXPIRATION_TIMEOUT) {
    358                 out.startTag(null, "password-expiration-timeout");
    359                 out.attribute(null, "value", Long.toString(passwordExpirationTimeout));
    360                 out.endTag(null, "password-expiration-timeout");
    361             }
    362             if (passwordExpirationDate != DEF_PASSWORD_EXPIRATION_DATE) {
    363                 out.startTag(null, "password-expiration-date");
    364                 out.attribute(null, "value", Long.toString(passwordExpirationDate));
    365                 out.endTag(null, "password-expiration-date");
    366             }
    367             if (encryptionRequested) {
    368                 out.startTag(null, "encryption-requested");
    369                 out.attribute(null, "value", Boolean.toString(encryptionRequested));
    370                 out.endTag(null, "encryption-requested");
    371             }
    372             if (disableCamera) {
    373                 out.startTag(null, "disable-camera");
    374                 out.attribute(null, "value", Boolean.toString(disableCamera));
    375                 out.endTag(null, "disable-camera");
    376             }
    377             if (disabledKeyguardFeatures != DEF_KEYGUARD_FEATURES_DISABLED) {
    378                 out.startTag(null, "disable-keyguard-features");
    379                 out.attribute(null, "value", Integer.toString(disabledKeyguardFeatures));
    380                 out.endTag(null, "disable-keyguard-features");
    381             }
    382         }
    383 
    384         void readFromXml(XmlPullParser parser)
    385                 throws XmlPullParserException, IOException {
    386             int outerDepth = parser.getDepth();
    387             int type;
    388             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
    389                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
    390                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
    391                     continue;
    392                 }
    393                 String tag = parser.getName();
    394                 if ("policies".equals(tag)) {
    395                     info.readPoliciesFromXml(parser);
    396                 } else if ("password-quality".equals(tag)) {
    397                     passwordQuality = Integer.parseInt(
    398                             parser.getAttributeValue(null, "value"));
    399                 } else if ("min-password-length".equals(tag)) {
    400                     minimumPasswordLength = Integer.parseInt(
    401                             parser.getAttributeValue(null, "value"));
    402                 } else if ("password-history-length".equals(tag)) {
    403                     passwordHistoryLength = Integer.parseInt(
    404                             parser.getAttributeValue(null, "value"));
    405                 } else if ("min-password-uppercase".equals(tag)) {
    406                     minimumPasswordUpperCase = Integer.parseInt(
    407                             parser.getAttributeValue(null, "value"));
    408                 } else if ("min-password-lowercase".equals(tag)) {
    409                     minimumPasswordLowerCase = Integer.parseInt(
    410                             parser.getAttributeValue(null, "value"));
    411                 } else if ("min-password-letters".equals(tag)) {
    412                     minimumPasswordLetters = Integer.parseInt(
    413                             parser.getAttributeValue(null, "value"));
    414                 } else if ("min-password-numeric".equals(tag)) {
    415                     minimumPasswordNumeric = Integer.parseInt(
    416                             parser.getAttributeValue(null, "value"));
    417                 } else if ("min-password-symbols".equals(tag)) {
    418                     minimumPasswordSymbols = Integer.parseInt(
    419                             parser.getAttributeValue(null, "value"));
    420                 } else if ("min-password-nonletter".equals(tag)) {
    421                     minimumPasswordNonLetter = Integer.parseInt(
    422                             parser.getAttributeValue(null, "value"));
    423                 } else if ("max-time-to-unlock".equals(tag)) {
    424                     maximumTimeToUnlock = Long.parseLong(
    425                             parser.getAttributeValue(null, "value"));
    426                 } else if ("max-failed-password-wipe".equals(tag)) {
    427                     maximumFailedPasswordsForWipe = Integer.parseInt(
    428                             parser.getAttributeValue(null, "value"));
    429                 } else if ("specifies-global-proxy".equals(tag)) {
    430                     specifiesGlobalProxy = Boolean.parseBoolean(
    431                             parser.getAttributeValue(null, "value"));
    432                 } else if ("global-proxy-spec".equals(tag)) {
    433                     globalProxySpec =
    434                         parser.getAttributeValue(null, "value");
    435                 } else if ("global-proxy-exclusion-list".equals(tag)) {
    436                     globalProxyExclusionList =
    437                         parser.getAttributeValue(null, "value");
    438                 } else if ("password-expiration-timeout".equals(tag)) {
    439                     passwordExpirationTimeout = Long.parseLong(
    440                             parser.getAttributeValue(null, "value"));
    441                 } else if ("password-expiration-date".equals(tag)) {
    442                     passwordExpirationDate = Long.parseLong(
    443                             parser.getAttributeValue(null, "value"));
    444                 } else if ("encryption-requested".equals(tag)) {
    445                     encryptionRequested = Boolean.parseBoolean(
    446                             parser.getAttributeValue(null, "value"));
    447                 } else if ("disable-camera".equals(tag)) {
    448                     disableCamera = Boolean.parseBoolean(
    449                             parser.getAttributeValue(null, "value"));
    450                 } else if ("disable-keyguard-features".equals(tag)) {
    451                     disabledKeyguardFeatures = Integer.parseInt(
    452                             parser.getAttributeValue(null, "value"));
    453                 } else {
    454                     Slog.w(TAG, "Unknown admin tag: " + tag);
    455                 }
    456                 XmlUtils.skipCurrentTag(parser);
    457             }
    458         }
    459 
    460         void dump(String prefix, PrintWriter pw) {
    461             pw.print(prefix); pw.print("uid="); pw.println(getUid());
    462             pw.print(prefix); pw.println("policies:");
    463             ArrayList<DeviceAdminInfo.PolicyInfo> pols = info.getUsedPolicies();
    464             if (pols != null) {
    465                 for (int i=0; i<pols.size(); i++) {
    466                     pw.print(prefix); pw.print("  "); pw.println(pols.get(i).tag);
    467                 }
    468             }
    469             pw.print(prefix); pw.print("passwordQuality=0x");
    470                     pw.println(Integer.toHexString(passwordQuality));
    471             pw.print(prefix); pw.print("minimumPasswordLength=");
    472                     pw.println(minimumPasswordLength);
    473             pw.print(prefix); pw.print("passwordHistoryLength=");
    474                     pw.println(passwordHistoryLength);
    475             pw.print(prefix); pw.print("minimumPasswordUpperCase=");
    476                     pw.println(minimumPasswordUpperCase);
    477             pw.print(prefix); pw.print("minimumPasswordLowerCase=");
    478                     pw.println(minimumPasswordLowerCase);
    479             pw.print(prefix); pw.print("minimumPasswordLetters=");
    480                     pw.println(minimumPasswordLetters);
    481             pw.print(prefix); pw.print("minimumPasswordNumeric=");
    482                     pw.println(minimumPasswordNumeric);
    483             pw.print(prefix); pw.print("minimumPasswordSymbols=");
    484                     pw.println(minimumPasswordSymbols);
    485             pw.print(prefix); pw.print("minimumPasswordNonLetter=");
    486                     pw.println(minimumPasswordNonLetter);
    487             pw.print(prefix); pw.print("maximumTimeToUnlock=");
    488                     pw.println(maximumTimeToUnlock);
    489             pw.print(prefix); pw.print("maximumFailedPasswordsForWipe=");
    490                     pw.println(maximumFailedPasswordsForWipe);
    491             pw.print(prefix); pw.print("specifiesGlobalProxy=");
    492                     pw.println(specifiesGlobalProxy);
    493             pw.print(prefix); pw.print("passwordExpirationTimeout=");
    494                     pw.println(passwordExpirationTimeout);
    495             pw.print(prefix); pw.print("passwordExpirationDate=");
    496                     pw.println(passwordExpirationDate);
    497             if (globalProxySpec != null) {
    498                 pw.print(prefix); pw.print("globalProxySpec=");
    499                         pw.println(globalProxySpec);
    500             }
    501             if (globalProxyExclusionList != null) {
    502                 pw.print(prefix); pw.print("globalProxyEclusionList=");
    503                         pw.println(globalProxyExclusionList);
    504             }
    505             pw.print(prefix); pw.print("encryptionRequested=");
    506                     pw.println(encryptionRequested);
    507             pw.print(prefix); pw.print("disableCamera=");
    508                     pw.println(disableCamera);
    509             pw.print(prefix); pw.print("disabledKeyguardFeatures=");
    510                     pw.println(disabledKeyguardFeatures);
    511         }
    512     }
    513 
    514     private void handlePackagesChanged(int userHandle) {
    515         boolean removed = false;
    516         if (DBG) Slog.d(TAG, "Handling package changes for user " + userHandle);
    517         DevicePolicyData policy = getUserData(userHandle);
    518         IPackageManager pm = AppGlobals.getPackageManager();
    519         for (int i = policy.mAdminList.size() - 1; i >= 0; i--) {
    520             ActiveAdmin aa = policy.mAdminList.get(i);
    521             try {
    522                 if (pm.getPackageInfo(aa.info.getPackageName(), 0, userHandle) == null
    523                         || pm.getReceiverInfo(aa.info.getComponent(), 0, userHandle) == null) {
    524                     removed = true;
    525                     policy.mAdminList.remove(i);
    526                     policy.mAdminMap.remove(aa.info.getComponent());
    527                 }
    528             } catch (RemoteException re) {
    529                 // Shouldn't happen
    530             }
    531         }
    532         if (removed) {
    533             validatePasswordOwnerLocked(policy);
    534             syncDeviceCapabilitiesLocked(policy);
    535             saveSettingsLocked(policy.mUserHandle);
    536         }
    537     }
    538 
    539     /**
    540      * Instantiates the service.
    541      */
    542     public DevicePolicyManagerService(Context context) {
    543         mContext = context;
    544         mHasFeature = context.getPackageManager().hasSystemFeature(
    545                 PackageManager.FEATURE_DEVICE_ADMIN);
    546         mWakeLock = ((PowerManager)context.getSystemService(Context.POWER_SERVICE))
    547                 .newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DPM");
    548         if (!mHasFeature) {
    549             // Skip the rest of the initialization
    550             return;
    551         }
    552         IntentFilter filter = new IntentFilter();
    553         filter.addAction(Intent.ACTION_BOOT_COMPLETED);
    554         filter.addAction(ACTION_EXPIRED_PASSWORD_NOTIFICATION);
    555         filter.addAction(Intent.ACTION_USER_REMOVED);
    556         filter.addAction(Intent.ACTION_USER_STARTED);
    557         filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
    558         context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
    559         filter = new IntentFilter();
    560         filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
    561         filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
    562         filter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
    563         filter.addAction(Intent.ACTION_PACKAGE_ADDED);
    564         filter.addDataScheme("package");
    565         context.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, mHandler);
    566     }
    567 
    568     /**
    569      * Creates and loads the policy data from xml.
    570      * @param userHandle the user for whom to load the policy data
    571      * @return
    572      */
    573     DevicePolicyData getUserData(int userHandle) {
    574         synchronized (this) {
    575             DevicePolicyData policy = mUserData.get(userHandle);
    576             if (policy == null) {
    577                 policy = new DevicePolicyData(userHandle);
    578                 mUserData.append(userHandle, policy);
    579                 loadSettingsLocked(policy, userHandle);
    580             }
    581             return policy;
    582         }
    583     }
    584 
    585     void removeUserData(int userHandle) {
    586         synchronized (this) {
    587             if (userHandle == UserHandle.USER_OWNER) {
    588                 Slog.w(TAG, "Tried to remove device policy file for user 0! Ignoring.");
    589                 return;
    590             }
    591             DevicePolicyData policy = mUserData.get(userHandle);
    592             if (policy != null) {
    593                 mUserData.remove(userHandle);
    594             }
    595             File policyFile = new File(Environment.getUserSystemDirectory(userHandle),
    596                     DEVICE_POLICIES_XML);
    597             policyFile.delete();
    598             Slog.i(TAG, "Removed device policy file " + policyFile.getAbsolutePath());
    599         }
    600     }
    601 
    602     void loadDeviceOwner() {
    603         synchronized (this) {
    604             if (DeviceOwner.isRegistered()) {
    605                 mDeviceOwner = new DeviceOwner();
    606             }
    607         }
    608     }
    609 
    610     /**
    611      * Set an alarm for an upcoming event - expiration warning, expiration, or post-expiration
    612      * reminders.  Clears alarm if no expirations are configured.
    613      */
    614     protected void setExpirationAlarmCheckLocked(Context context, DevicePolicyData policy) {
    615         final long expiration = getPasswordExpirationLocked(null, policy.mUserHandle);
    616         final long now = System.currentTimeMillis();
    617         final long timeToExpire = expiration - now;
    618         final long alarmTime;
    619         if (expiration == 0) {
    620             // No expirations are currently configured:  Cancel alarm.
    621             alarmTime = 0;
    622         } else if (timeToExpire <= 0) {
    623             // The password has already expired:  Repeat every 24 hours.
    624             alarmTime = now + MS_PER_DAY;
    625         } else {
    626             // Selecting the next alarm time:  Roll forward to the next 24 hour multiple before
    627             // the expiration time.
    628             long alarmInterval = timeToExpire % MS_PER_DAY;
    629             if (alarmInterval == 0) {
    630                 alarmInterval = MS_PER_DAY;
    631             }
    632             alarmTime = now + alarmInterval;
    633         }
    634 
    635         long token = Binder.clearCallingIdentity();
    636         try {
    637             AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    638             PendingIntent pi = PendingIntent.getBroadcastAsUser(context, REQUEST_EXPIRE_PASSWORD,
    639                     new Intent(ACTION_EXPIRED_PASSWORD_NOTIFICATION),
    640                     PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_UPDATE_CURRENT,
    641                     new UserHandle(policy.mUserHandle));
    642             am.cancel(pi);
    643             if (alarmTime != 0) {
    644                 am.set(AlarmManager.RTC, alarmTime, pi);
    645             }
    646         } finally {
    647             Binder.restoreCallingIdentity(token);
    648         }
    649     }
    650 
    651     private IPowerManager getIPowerManager() {
    652         if (mIPowerManager == null) {
    653             IBinder b = ServiceManager.getService(Context.POWER_SERVICE);
    654             mIPowerManager = IPowerManager.Stub.asInterface(b);
    655         }
    656         return mIPowerManager;
    657     }
    658 
    659     private IWindowManager getWindowManager() {
    660         if (mIWindowManager == null) {
    661             IBinder b = ServiceManager.getService(Context.WINDOW_SERVICE);
    662             mIWindowManager = IWindowManager.Stub.asInterface(b);
    663         }
    664         return mIWindowManager;
    665     }
    666 
    667     private NotificationManager getNotificationManager() {
    668         if (mNotificationManager == null) {
    669             mNotificationManager =
    670                     (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
    671         }
    672         return mNotificationManager;
    673     }
    674 
    675     ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who, int userHandle) {
    676         ActiveAdmin admin = getUserData(userHandle).mAdminMap.get(who);
    677         if (admin != null
    678                 && who.getPackageName().equals(admin.info.getActivityInfo().packageName)
    679                 && who.getClassName().equals(admin.info.getActivityInfo().name)) {
    680             return admin;
    681         }
    682         return null;
    683     }
    684 
    685     ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy)
    686             throws SecurityException {
    687         final int callingUid = Binder.getCallingUid();
    688         final int userHandle = UserHandle.getUserId(callingUid);
    689         final DevicePolicyData policy = getUserData(userHandle);
    690         if (who != null) {
    691             ActiveAdmin admin = policy.mAdminMap.get(who);
    692             if (admin == null) {
    693                 throw new SecurityException("No active admin " + who);
    694             }
    695             if (admin.getUid() != callingUid) {
    696                 throw new SecurityException("Admin " + who + " is not owned by uid "
    697                         + Binder.getCallingUid());
    698             }
    699             if (!admin.info.usesPolicy(reqPolicy)) {
    700                 throw new SecurityException("Admin " + admin.info.getComponent()
    701                         + " did not specify uses-policy for: "
    702                         + admin.info.getTagForPolicy(reqPolicy));
    703             }
    704             return admin;
    705         } else {
    706             final int N = policy.mAdminList.size();
    707             for (int i=0; i<N; i++) {
    708                 ActiveAdmin admin = policy.mAdminList.get(i);
    709                 if (admin.getUid() == callingUid && admin.info.usesPolicy(reqPolicy)) {
    710                     return admin;
    711                 }
    712             }
    713             throw new SecurityException("No active admin owned by uid "
    714                     + Binder.getCallingUid() + " for policy #" + reqPolicy);
    715         }
    716     }
    717 
    718     void sendAdminCommandLocked(ActiveAdmin admin, String action) {
    719         sendAdminCommandLocked(admin, action, null);
    720     }
    721 
    722     void sendAdminCommandLocked(ActiveAdmin admin, String action, BroadcastReceiver result) {
    723         Intent intent = new Intent(action);
    724         intent.setComponent(admin.info.getComponent());
    725         if (action.equals(DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING)) {
    726             intent.putExtra("expiration", admin.passwordExpirationDate);
    727         }
    728         if (result != null) {
    729             mContext.sendOrderedBroadcastAsUser(intent, admin.getUserHandle(),
    730                     null, result, mHandler, Activity.RESULT_OK, null, null);
    731         } else {
    732             mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
    733         }
    734     }
    735 
    736     void sendAdminCommandLocked(String action, int reqPolicy, int userHandle) {
    737         final DevicePolicyData policy = getUserData(userHandle);
    738         final int count = policy.mAdminList.size();
    739         if (count > 0) {
    740             for (int i = 0; i < count; i++) {
    741                 ActiveAdmin admin = policy.mAdminList.get(i);
    742                 if (admin.info.usesPolicy(reqPolicy)) {
    743                     sendAdminCommandLocked(admin, action);
    744                 }
    745             }
    746         }
    747     }
    748 
    749     void removeActiveAdminLocked(final ComponentName adminReceiver, int userHandle) {
    750         final ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
    751         if (admin != null) {
    752             sendAdminCommandLocked(admin,
    753                     DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED,
    754                     new BroadcastReceiver() {
    755                         @Override
    756                         public void onReceive(Context context, Intent intent) {
    757                             synchronized (DevicePolicyManagerService.this) {
    758                                 int userHandle = admin.getUserHandle().getIdentifier();
    759                                 DevicePolicyData policy = getUserData(userHandle);
    760                                 boolean doProxyCleanup = admin.info.usesPolicy(
    761                                         DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
    762                                 policy.mAdminList.remove(admin);
    763                                 policy.mAdminMap.remove(adminReceiver);
    764                                 validatePasswordOwnerLocked(policy);
    765                                 syncDeviceCapabilitiesLocked(policy);
    766                                 if (doProxyCleanup) {
    767                                     resetGlobalProxyLocked(getUserData(userHandle));
    768                                 }
    769                                 saveSettingsLocked(userHandle);
    770                                 updateMaximumTimeToLockLocked(policy);
    771                             }
    772                         }
    773             });
    774         }
    775     }
    776 
    777     public DeviceAdminInfo findAdmin(ComponentName adminName, int userHandle) {
    778         if (!mHasFeature) {
    779             return null;
    780         }
    781         enforceCrossUserPermission(userHandle);
    782         Intent resolveIntent = new Intent();
    783         resolveIntent.setComponent(adminName);
    784         List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceivers(
    785                 resolveIntent,
    786                 PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
    787                 userHandle);
    788         if (infos == null || infos.size() <= 0) {
    789             throw new IllegalArgumentException("Unknown admin: " + adminName);
    790         }
    791 
    792         try {
    793             return new DeviceAdminInfo(mContext, infos.get(0));
    794         } catch (XmlPullParserException e) {
    795             Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e);
    796             return null;
    797         } catch (IOException e) {
    798             Slog.w(TAG, "Bad device admin requested for user=" + userHandle + ": " + adminName, e);
    799             return null;
    800         }
    801     }
    802 
    803     private static JournaledFile makeJournaledFile(int userHandle) {
    804         final String base = userHandle == 0
    805                 ? "/data/system/" + DEVICE_POLICIES_XML
    806                 : new File(Environment.getUserSystemDirectory(userHandle), DEVICE_POLICIES_XML)
    807                         .getAbsolutePath();
    808         return new JournaledFile(new File(base), new File(base + ".tmp"));
    809     }
    810 
    811     private void saveSettingsLocked(int userHandle) {
    812         DevicePolicyData policy = getUserData(userHandle);
    813         JournaledFile journal = makeJournaledFile(userHandle);
    814         FileOutputStream stream = null;
    815         try {
    816             stream = new FileOutputStream(journal.chooseForWrite(), false);
    817             XmlSerializer out = new FastXmlSerializer();
    818             out.setOutput(stream, "utf-8");
    819             out.startDocument(null, true);
    820 
    821             out.startTag(null, "policies");
    822 
    823             final int N = policy.mAdminList.size();
    824             for (int i=0; i<N; i++) {
    825                 ActiveAdmin ap = policy.mAdminList.get(i);
    826                 if (ap != null) {
    827                     out.startTag(null, "admin");
    828                     out.attribute(null, "name", ap.info.getComponent().flattenToString());
    829                     ap.writeToXml(out);
    830                     out.endTag(null, "admin");
    831                 }
    832             }
    833 
    834             if (policy.mPasswordOwner >= 0) {
    835                 out.startTag(null, "password-owner");
    836                 out.attribute(null, "value", Integer.toString(policy.mPasswordOwner));
    837                 out.endTag(null, "password-owner");
    838             }
    839 
    840             if (policy.mFailedPasswordAttempts != 0) {
    841                 out.startTag(null, "failed-password-attempts");
    842                 out.attribute(null, "value", Integer.toString(policy.mFailedPasswordAttempts));
    843                 out.endTag(null, "failed-password-attempts");
    844             }
    845 
    846             if (policy.mActivePasswordQuality != 0 || policy.mActivePasswordLength != 0
    847                     || policy.mActivePasswordUpperCase != 0 || policy.mActivePasswordLowerCase != 0
    848                     || policy.mActivePasswordLetters != 0 || policy.mActivePasswordNumeric != 0
    849                     || policy.mActivePasswordSymbols != 0 || policy.mActivePasswordNonLetter != 0) {
    850                 out.startTag(null, "active-password");
    851                 out.attribute(null, "quality", Integer.toString(policy.mActivePasswordQuality));
    852                 out.attribute(null, "length", Integer.toString(policy.mActivePasswordLength));
    853                 out.attribute(null, "uppercase", Integer.toString(policy.mActivePasswordUpperCase));
    854                 out.attribute(null, "lowercase", Integer.toString(policy.mActivePasswordLowerCase));
    855                 out.attribute(null, "letters", Integer.toString(policy.mActivePasswordLetters));
    856                 out.attribute(null, "numeric", Integer
    857                         .toString(policy.mActivePasswordNumeric));
    858                 out.attribute(null, "symbols", Integer.toString(policy.mActivePasswordSymbols));
    859                 out.attribute(null, "nonletter", Integer.toString(policy.mActivePasswordNonLetter));
    860                 out.endTag(null, "active-password");
    861             }
    862 
    863             out.endTag(null, "policies");
    864 
    865             out.endDocument();
    866             stream.close();
    867             journal.commit();
    868             sendChangedNotification(userHandle);
    869         } catch (IOException e) {
    870             try {
    871                 if (stream != null) {
    872                     stream.close();
    873                 }
    874             } catch (IOException ex) {
    875                 // Ignore
    876             }
    877             journal.rollback();
    878         }
    879     }
    880 
    881     private void sendChangedNotification(int userHandle) {
    882         Intent intent = new Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
    883         intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
    884         long ident = Binder.clearCallingIdentity();
    885         try {
    886             mContext.sendBroadcastAsUser(intent, new UserHandle(userHandle));
    887         } finally {
    888             Binder.restoreCallingIdentity(ident);
    889         }
    890     }
    891 
    892     private void loadSettingsLocked(DevicePolicyData policy, int userHandle) {
    893         JournaledFile journal = makeJournaledFile(userHandle);
    894         FileInputStream stream = null;
    895         File file = journal.chooseForRead();
    896         try {
    897             stream = new FileInputStream(file);
    898             XmlPullParser parser = Xml.newPullParser();
    899             parser.setInput(stream, null);
    900 
    901             int type;
    902             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
    903                     && type != XmlPullParser.START_TAG) {
    904             }
    905             String tag = parser.getName();
    906             if (!"policies".equals(tag)) {
    907                 throw new XmlPullParserException(
    908                         "Settings do not start with policies tag: found " + tag);
    909             }
    910             type = parser.next();
    911             int outerDepth = parser.getDepth();
    912             while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
    913                    && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
    914                 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
    915                     continue;
    916                 }
    917                 tag = parser.getName();
    918                 if ("admin".equals(tag)) {
    919                     String name = parser.getAttributeValue(null, "name");
    920                     try {
    921                         DeviceAdminInfo dai = findAdmin(
    922                                 ComponentName.unflattenFromString(name), userHandle);
    923                         if (DBG && (UserHandle.getUserId(dai.getActivityInfo().applicationInfo.uid)
    924                                 != userHandle)) {
    925                             Slog.w(TAG, "findAdmin returned an incorrect uid "
    926                                     + dai.getActivityInfo().applicationInfo.uid + " for user "
    927                                     + userHandle);
    928                         }
    929                         if (dai != null) {
    930                             ActiveAdmin ap = new ActiveAdmin(dai);
    931                             ap.readFromXml(parser);
    932                             policy.mAdminMap.put(ap.info.getComponent(), ap);
    933                             policy.mAdminList.add(ap);
    934                         }
    935                     } catch (RuntimeException e) {
    936                         Slog.w(TAG, "Failed loading admin " + name, e);
    937                     }
    938                 } else if ("failed-password-attempts".equals(tag)) {
    939                     policy.mFailedPasswordAttempts = Integer.parseInt(
    940                             parser.getAttributeValue(null, "value"));
    941                     XmlUtils.skipCurrentTag(parser);
    942                 } else if ("password-owner".equals(tag)) {
    943                     policy.mPasswordOwner = Integer.parseInt(
    944                             parser.getAttributeValue(null, "value"));
    945                     XmlUtils.skipCurrentTag(parser);
    946                 } else if ("active-password".equals(tag)) {
    947                     policy.mActivePasswordQuality = Integer.parseInt(
    948                             parser.getAttributeValue(null, "quality"));
    949                     policy.mActivePasswordLength = Integer.parseInt(
    950                             parser.getAttributeValue(null, "length"));
    951                     policy.mActivePasswordUpperCase = Integer.parseInt(
    952                             parser.getAttributeValue(null, "uppercase"));
    953                     policy.mActivePasswordLowerCase = Integer.parseInt(
    954                             parser.getAttributeValue(null, "lowercase"));
    955                     policy.mActivePasswordLetters = Integer.parseInt(
    956                             parser.getAttributeValue(null, "letters"));
    957                     policy.mActivePasswordNumeric = Integer.parseInt(
    958                             parser.getAttributeValue(null, "numeric"));
    959                     policy.mActivePasswordSymbols = Integer.parseInt(
    960                             parser.getAttributeValue(null, "symbols"));
    961                     policy.mActivePasswordNonLetter = Integer.parseInt(
    962                             parser.getAttributeValue(null, "nonletter"));
    963                     XmlUtils.skipCurrentTag(parser);
    964                 } else {
    965                     Slog.w(TAG, "Unknown tag: " + tag);
    966                     XmlUtils.skipCurrentTag(parser);
    967                 }
    968             }
    969         } catch (NullPointerException e) {
    970             Slog.w(TAG, "failed parsing " + file + " " + e);
    971         } catch (NumberFormatException e) {
    972             Slog.w(TAG, "failed parsing " + file + " " + e);
    973         } catch (XmlPullParserException e) {
    974             Slog.w(TAG, "failed parsing " + file + " " + e);
    975         } catch (FileNotFoundException e) {
    976             // Don't be noisy, this is normal if we haven't defined any policies.
    977         } catch (IOException e) {
    978             Slog.w(TAG, "failed parsing " + file + " " + e);
    979         } catch (IndexOutOfBoundsException e) {
    980             Slog.w(TAG, "failed parsing " + file + " " + e);
    981         }
    982         try {
    983             if (stream != null) {
    984                 stream.close();
    985             }
    986         } catch (IOException e) {
    987             // Ignore
    988         }
    989 
    990         // Validate that what we stored for the password quality matches
    991         // sufficiently what is currently set.  Note that this is only
    992         // a sanity check in case the two get out of sync; this should
    993         // never normally happen.
    994         LockPatternUtils utils = new LockPatternUtils(mContext);
    995         if (utils.getActivePasswordQuality() < policy.mActivePasswordQuality) {
    996             Slog.w(TAG, "Active password quality 0x"
    997                     + Integer.toHexString(policy.mActivePasswordQuality)
    998                     + " does not match actual quality 0x"
    999                     + Integer.toHexString(utils.getActivePasswordQuality()));
   1000             policy.mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
   1001             policy.mActivePasswordLength = 0;
   1002             policy.mActivePasswordUpperCase = 0;
   1003             policy.mActivePasswordLowerCase = 0;
   1004             policy.mActivePasswordLetters = 0;
   1005             policy.mActivePasswordNumeric = 0;
   1006             policy.mActivePasswordSymbols = 0;
   1007             policy.mActivePasswordNonLetter = 0;
   1008         }
   1009 
   1010         validatePasswordOwnerLocked(policy);
   1011         syncDeviceCapabilitiesLocked(policy);
   1012         updateMaximumTimeToLockLocked(policy);
   1013     }
   1014 
   1015     static void validateQualityConstant(int quality) {
   1016         switch (quality) {
   1017             case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
   1018             case DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK:
   1019             case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
   1020             case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
   1021             case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
   1022             case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
   1023             case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
   1024                 return;
   1025         }
   1026         throw new IllegalArgumentException("Invalid quality constant: 0x"
   1027                 + Integer.toHexString(quality));
   1028     }
   1029 
   1030     void validatePasswordOwnerLocked(DevicePolicyData policy) {
   1031         if (policy.mPasswordOwner >= 0) {
   1032             boolean haveOwner = false;
   1033             for (int i = policy.mAdminList.size() - 1; i >= 0; i--) {
   1034                 if (policy.mAdminList.get(i).getUid() == policy.mPasswordOwner) {
   1035                     haveOwner = true;
   1036                     break;
   1037                 }
   1038             }
   1039             if (!haveOwner) {
   1040                 Slog.w(TAG, "Previous password owner " + policy.mPasswordOwner
   1041                         + " no longer active; disabling");
   1042                 policy.mPasswordOwner = -1;
   1043             }
   1044         }
   1045     }
   1046 
   1047     /**
   1048      * Pushes down policy information to the system for any policies related to general device
   1049      * capabilities that need to be enforced by lower level services (e.g. Camera services).
   1050      */
   1051     void syncDeviceCapabilitiesLocked(DevicePolicyData policy) {
   1052         // Ensure the status of the camera is synced down to the system. Interested native services
   1053         // should monitor this value and act accordingly.
   1054         boolean systemState = SystemProperties.getBoolean(SYSTEM_PROP_DISABLE_CAMERA, false);
   1055         boolean cameraDisabled = getCameraDisabled(null, policy.mUserHandle);
   1056         if (cameraDisabled != systemState) {
   1057             long token = Binder.clearCallingIdentity();
   1058             try {
   1059                 String value = cameraDisabled ? "1" : "0";
   1060                 if (DBG) Slog.v(TAG, "Change in camera state ["
   1061                         + SYSTEM_PROP_DISABLE_CAMERA + "] = " + value);
   1062                 SystemProperties.set(SYSTEM_PROP_DISABLE_CAMERA, value);
   1063             } finally {
   1064                 Binder.restoreCallingIdentity(token);
   1065             }
   1066         }
   1067     }
   1068 
   1069     public void systemReady() {
   1070         if (!mHasFeature) {
   1071             return;
   1072         }
   1073         synchronized (this) {
   1074             loadSettingsLocked(getUserData(UserHandle.USER_OWNER), UserHandle.USER_OWNER);
   1075             loadDeviceOwner();
   1076         }
   1077     }
   1078 
   1079     private void handlePasswordExpirationNotification(DevicePolicyData policy) {
   1080         synchronized (this) {
   1081             final long now = System.currentTimeMillis();
   1082             final int N = policy.mAdminList.size();
   1083             if (N <= 0) {
   1084                 return;
   1085             }
   1086             for (int i=0; i < N; i++) {
   1087                 ActiveAdmin admin = policy.mAdminList.get(i);
   1088                 if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)
   1089                         && admin.passwordExpirationTimeout > 0L
   1090                         && admin.passwordExpirationDate > 0L
   1091                         && now >= admin.passwordExpirationDate - EXPIRATION_GRACE_PERIOD_MS) {
   1092                     sendAdminCommandLocked(admin, DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING);
   1093                 }
   1094             }
   1095             setExpirationAlarmCheckLocked(mContext, policy);
   1096         }
   1097     }
   1098 
   1099     private void manageMonitoringCertificateNotification(Intent intent) {
   1100         final NotificationManager notificationManager = getNotificationManager();
   1101 
   1102         final boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
   1103         if (! hasCert) {
   1104             if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
   1105                 UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
   1106                 for (UserInfo user : um.getUsers()) {
   1107                     notificationManager.cancelAsUser(
   1108                             null, MONITORING_CERT_NOTIFICATION_ID, user.getUserHandle());
   1109                 }
   1110             }
   1111             return;
   1112         }
   1113         final boolean isManaged = getDeviceOwner() != null;
   1114         int smallIconId;
   1115         String contentText;
   1116         if (isManaged) {
   1117             contentText = mContext.getString(R.string.ssl_ca_cert_noti_managed,
   1118                     getDeviceOwnerName());
   1119             smallIconId = R.drawable.stat_sys_certificate_info;
   1120         } else {
   1121             contentText = mContext.getString(R.string.ssl_ca_cert_noti_by_unknown);
   1122             smallIconId = android.R.drawable.stat_sys_warning;
   1123         }
   1124 
   1125         Intent dialogIntent = new Intent(Settings.ACTION_MONITORING_CERT_INFO);
   1126         dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
   1127         dialogIntent.setPackage("com.android.settings");
   1128         // Notification will be sent individually to all users. The activity should start as
   1129         // whichever user is current when it starts.
   1130         PendingIntent notifyIntent = PendingIntent.getActivityAsUser(mContext, 0, dialogIntent,
   1131                 PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT);
   1132 
   1133         Notification noti = new Notification.Builder(mContext)
   1134             .setSmallIcon(smallIconId)
   1135             .setContentTitle(mContext.getString(R.string.ssl_ca_cert_warning))
   1136             .setContentText(contentText)
   1137             .setContentIntent(notifyIntent)
   1138             .setPriority(Notification.PRIORITY_HIGH)
   1139             .setShowWhen(false)
   1140             .build();
   1141 
   1142         // If this is a boot intent, this will fire for each user. But if this is a storage changed
   1143         // intent, it will fire once, so we need to notify all users.
   1144         if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
   1145             UserManager um = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
   1146             for (UserInfo user : um.getUsers()) {
   1147                 notificationManager.notifyAsUser(
   1148                         null, MONITORING_CERT_NOTIFICATION_ID, noti, user.getUserHandle());
   1149             }
   1150         } else {
   1151             notificationManager.notifyAsUser(
   1152                     null, MONITORING_CERT_NOTIFICATION_ID, noti, UserHandle.CURRENT);
   1153         }
   1154     }
   1155 
   1156     /**
   1157      * @param adminReceiver The admin to add
   1158      * @param refreshing true = update an active admin, no error
   1159      */
   1160     public void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle) {
   1161         if (!mHasFeature) {
   1162             return;
   1163         }
   1164         mContext.enforceCallingOrSelfPermission(
   1165                 android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
   1166         enforceCrossUserPermission(userHandle);
   1167 
   1168         DevicePolicyData policy = getUserData(userHandle);
   1169         DeviceAdminInfo info = findAdmin(adminReceiver, userHandle);
   1170         if (info == null) {
   1171             throw new IllegalArgumentException("Bad admin: " + adminReceiver);
   1172         }
   1173         synchronized (this) {
   1174             long ident = Binder.clearCallingIdentity();
   1175             try {
   1176                 if (!refreshing && getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null) {
   1177                     throw new IllegalArgumentException("Admin is already added");
   1178                 }
   1179                 ActiveAdmin newAdmin = new ActiveAdmin(info);
   1180                 policy.mAdminMap.put(adminReceiver, newAdmin);
   1181                 int replaceIndex = -1;
   1182                 if (refreshing) {
   1183                     final int N = policy.mAdminList.size();
   1184                     for (int i=0; i < N; i++) {
   1185                         ActiveAdmin oldAdmin = policy.mAdminList.get(i);
   1186                         if (oldAdmin.info.getComponent().equals(adminReceiver)) {
   1187                             replaceIndex = i;
   1188                             break;
   1189                         }
   1190                     }
   1191                 }
   1192                 if (replaceIndex == -1) {
   1193                     policy.mAdminList.add(newAdmin);
   1194                     enableIfNecessary(info.getPackageName(), userHandle);
   1195                 } else {
   1196                     policy.mAdminList.set(replaceIndex, newAdmin);
   1197                 }
   1198                 saveSettingsLocked(userHandle);
   1199                 sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED);
   1200             } finally {
   1201                 Binder.restoreCallingIdentity(ident);
   1202             }
   1203         }
   1204     }
   1205 
   1206     public boolean isAdminActive(ComponentName adminReceiver, int userHandle) {
   1207         if (!mHasFeature) {
   1208             return false;
   1209         }
   1210         enforceCrossUserPermission(userHandle);
   1211         synchronized (this) {
   1212             return getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null;
   1213         }
   1214     }
   1215 
   1216     public boolean hasGrantedPolicy(ComponentName adminReceiver, int policyId, int userHandle) {
   1217         if (!mHasFeature) {
   1218             return false;
   1219         }
   1220         enforceCrossUserPermission(userHandle);
   1221         synchronized (this) {
   1222             ActiveAdmin administrator = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
   1223             if (administrator == null) {
   1224                 throw new SecurityException("No active admin " + adminReceiver);
   1225             }
   1226             return administrator.info.usesPolicy(policyId);
   1227         }
   1228     }
   1229 
   1230     @SuppressWarnings("unchecked")
   1231     public List<ComponentName> getActiveAdmins(int userHandle) {
   1232         if (!mHasFeature) {
   1233             return Collections.EMPTY_LIST;
   1234         }
   1235 
   1236         enforceCrossUserPermission(userHandle);
   1237         synchronized (this) {
   1238             DevicePolicyData policy = getUserData(userHandle);
   1239             final int N = policy.mAdminList.size();
   1240             if (N <= 0) {
   1241                 return null;
   1242             }
   1243             ArrayList<ComponentName> res = new ArrayList<ComponentName>(N);
   1244             for (int i=0; i<N; i++) {
   1245                 res.add(policy.mAdminList.get(i).info.getComponent());
   1246             }
   1247             return res;
   1248         }
   1249     }
   1250 
   1251     public boolean packageHasActiveAdmins(String packageName, int userHandle) {
   1252         if (!mHasFeature) {
   1253             return false;
   1254         }
   1255         enforceCrossUserPermission(userHandle);
   1256         synchronized (this) {
   1257             DevicePolicyData policy = getUserData(userHandle);
   1258             final int N = policy.mAdminList.size();
   1259             for (int i=0; i<N; i++) {
   1260                 if (policy.mAdminList.get(i).info.getPackageName().equals(packageName)) {
   1261                     return true;
   1262                 }
   1263             }
   1264             return false;
   1265         }
   1266     }
   1267 
   1268     public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) {
   1269         if (!mHasFeature) {
   1270             return;
   1271         }
   1272         enforceCrossUserPermission(userHandle);
   1273         synchronized (this) {
   1274             ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
   1275             if (admin == null) {
   1276                 return;
   1277             }
   1278             if (admin.getUid() != Binder.getCallingUid()) {
   1279                 // If trying to remove device owner, refuse when the caller is not the owner.
   1280                 if (mDeviceOwner != null
   1281                         && adminReceiver.getPackageName().equals(mDeviceOwner.getPackageName())) {
   1282                     return;
   1283                 }
   1284                 mContext.enforceCallingOrSelfPermission(
   1285                         android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
   1286             }
   1287             long ident = Binder.clearCallingIdentity();
   1288             try {
   1289                 removeActiveAdminLocked(adminReceiver, userHandle);
   1290             } finally {
   1291                 Binder.restoreCallingIdentity(ident);
   1292             }
   1293         }
   1294     }
   1295 
   1296     public void setPasswordQuality(ComponentName who, int quality, int userHandle) {
   1297         if (!mHasFeature) {
   1298             return;
   1299         }
   1300         validateQualityConstant(quality);
   1301         enforceCrossUserPermission(userHandle);
   1302 
   1303         synchronized (this) {
   1304             if (who == null) {
   1305                 throw new NullPointerException("ComponentName is null");
   1306             }
   1307             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1308                     DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
   1309             if (ap.passwordQuality != quality) {
   1310                 ap.passwordQuality = quality;
   1311                 saveSettingsLocked(userHandle);
   1312             }
   1313         }
   1314     }
   1315 
   1316     public int getPasswordQuality(ComponentName who, int userHandle) {
   1317         if (!mHasFeature) {
   1318             return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
   1319         }
   1320         enforceCrossUserPermission(userHandle);
   1321         synchronized (this) {
   1322             int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
   1323             DevicePolicyData policy = getUserData(userHandle);
   1324 
   1325             if (who != null) {
   1326                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1327                 return admin != null ? admin.passwordQuality : mode;
   1328             }
   1329 
   1330             final int N = policy.mAdminList.size();
   1331             for  (int i=0; i<N; i++) {
   1332                 ActiveAdmin admin = policy.mAdminList.get(i);
   1333                 if (mode < admin.passwordQuality) {
   1334                     mode = admin.passwordQuality;
   1335                 }
   1336             }
   1337             return mode;
   1338         }
   1339     }
   1340 
   1341     public void setPasswordMinimumLength(ComponentName who, int length, int userHandle) {
   1342         if (!mHasFeature) {
   1343             return;
   1344         }
   1345         enforceCrossUserPermission(userHandle);
   1346         synchronized (this) {
   1347             if (who == null) {
   1348                 throw new NullPointerException("ComponentName is null");
   1349             }
   1350             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1351                     DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
   1352             if (ap.minimumPasswordLength != length) {
   1353                 ap.minimumPasswordLength = length;
   1354                 saveSettingsLocked(userHandle);
   1355             }
   1356         }
   1357     }
   1358 
   1359     public int getPasswordMinimumLength(ComponentName who, int userHandle) {
   1360         if (!mHasFeature) {
   1361             return 0;
   1362         }
   1363         enforceCrossUserPermission(userHandle);
   1364         synchronized (this) {
   1365             DevicePolicyData policy = getUserData(userHandle);
   1366             int length = 0;
   1367 
   1368             if (who != null) {
   1369                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1370                 return admin != null ? admin.minimumPasswordLength : length;
   1371             }
   1372 
   1373             final int N = policy.mAdminList.size();
   1374             for  (int i=0; i<N; i++) {
   1375                 ActiveAdmin admin = policy.mAdminList.get(i);
   1376                 if (length < admin.minimumPasswordLength) {
   1377                     length = admin.minimumPasswordLength;
   1378                 }
   1379             }
   1380             return length;
   1381         }
   1382     }
   1383 
   1384     public void setPasswordHistoryLength(ComponentName who, int length, int userHandle) {
   1385         if (!mHasFeature) {
   1386             return;
   1387         }
   1388         enforceCrossUserPermission(userHandle);
   1389         synchronized (this) {
   1390             if (who == null) {
   1391                 throw new NullPointerException("ComponentName is null");
   1392             }
   1393             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1394                     DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
   1395             if (ap.passwordHistoryLength != length) {
   1396                 ap.passwordHistoryLength = length;
   1397                 saveSettingsLocked(userHandle);
   1398             }
   1399         }
   1400     }
   1401 
   1402     public int getPasswordHistoryLength(ComponentName who, int userHandle) {
   1403         if (!mHasFeature) {
   1404             return 0;
   1405         }
   1406         enforceCrossUserPermission(userHandle);
   1407         synchronized (this) {
   1408             DevicePolicyData policy = getUserData(userHandle);
   1409             int length = 0;
   1410 
   1411             if (who != null) {
   1412                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1413                 return admin != null ? admin.passwordHistoryLength : length;
   1414             }
   1415 
   1416             final int N = policy.mAdminList.size();
   1417             for (int i = 0; i < N; i++) {
   1418                 ActiveAdmin admin = policy.mAdminList.get(i);
   1419                 if (length < admin.passwordHistoryLength) {
   1420                     length = admin.passwordHistoryLength;
   1421                 }
   1422             }
   1423             return length;
   1424         }
   1425     }
   1426 
   1427     public void setPasswordExpirationTimeout(ComponentName who, long timeout, int userHandle) {
   1428         if (!mHasFeature) {
   1429             return;
   1430         }
   1431         enforceCrossUserPermission(userHandle);
   1432         synchronized (this) {
   1433             if (who == null) {
   1434                 throw new NullPointerException("ComponentName is null");
   1435             }
   1436             if (timeout < 0) {
   1437                 throw new IllegalArgumentException("Timeout must be >= 0 ms");
   1438             }
   1439             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1440                     DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD);
   1441             // Calling this API automatically bumps the expiration date
   1442             final long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
   1443             ap.passwordExpirationDate = expiration;
   1444             ap.passwordExpirationTimeout = timeout;
   1445             if (timeout > 0L) {
   1446                 Slog.w(TAG, "setPasswordExpiration(): password will expire on "
   1447                         + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT)
   1448                         .format(new Date(expiration)));
   1449             }
   1450             saveSettingsLocked(userHandle);
   1451             // in case this is the first one
   1452             setExpirationAlarmCheckLocked(mContext, getUserData(userHandle));
   1453         }
   1454     }
   1455 
   1456     /**
   1457      * Return a single admin's expiration cycle time, or the min of all cycle times.
   1458      * Returns 0 if not configured.
   1459      */
   1460     public long getPasswordExpirationTimeout(ComponentName who, int userHandle) {
   1461         if (!mHasFeature) {
   1462             return 0L;
   1463         }
   1464         enforceCrossUserPermission(userHandle);
   1465         synchronized (this) {
   1466             if (who != null) {
   1467                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1468                 return admin != null ? admin.passwordExpirationTimeout : 0L;
   1469             }
   1470 
   1471             long timeout = 0L;
   1472             DevicePolicyData policy = getUserData(userHandle);
   1473             final int N = policy.mAdminList.size();
   1474             for (int i = 0; i < N; i++) {
   1475                 ActiveAdmin admin = policy.mAdminList.get(i);
   1476                 if (timeout == 0L || (admin.passwordExpirationTimeout != 0L
   1477                         && timeout > admin.passwordExpirationTimeout)) {
   1478                     timeout = admin.passwordExpirationTimeout;
   1479                 }
   1480             }
   1481             return timeout;
   1482         }
   1483     }
   1484 
   1485     /**
   1486      * Return a single admin's expiration date/time, or the min (soonest) for all admins.
   1487      * Returns 0 if not configured.
   1488      */
   1489     private long getPasswordExpirationLocked(ComponentName who, int userHandle) {
   1490         if (who != null) {
   1491             ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1492             return admin != null ? admin.passwordExpirationDate : 0L;
   1493         }
   1494 
   1495         long timeout = 0L;
   1496         DevicePolicyData policy = getUserData(userHandle);
   1497         final int N = policy.mAdminList.size();
   1498         for (int i = 0; i < N; i++) {
   1499             ActiveAdmin admin = policy.mAdminList.get(i);
   1500             if (timeout == 0L || (admin.passwordExpirationDate != 0
   1501                     && timeout > admin.passwordExpirationDate)) {
   1502                 timeout = admin.passwordExpirationDate;
   1503             }
   1504         }
   1505         return timeout;
   1506     }
   1507 
   1508     public long getPasswordExpiration(ComponentName who, int userHandle) {
   1509         if (!mHasFeature) {
   1510             return 0L;
   1511         }
   1512         enforceCrossUserPermission(userHandle);
   1513         synchronized (this) {
   1514             return getPasswordExpirationLocked(who, userHandle);
   1515         }
   1516     }
   1517 
   1518     public void setPasswordMinimumUpperCase(ComponentName who, int length, int userHandle) {
   1519         if (!mHasFeature) {
   1520             return;
   1521         }
   1522         enforceCrossUserPermission(userHandle);
   1523         synchronized (this) {
   1524             if (who == null) {
   1525                 throw new NullPointerException("ComponentName is null");
   1526             }
   1527             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1528                     DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
   1529             if (ap.minimumPasswordUpperCase != length) {
   1530                 ap.minimumPasswordUpperCase = length;
   1531                 saveSettingsLocked(userHandle);
   1532             }
   1533         }
   1534     }
   1535 
   1536     public int getPasswordMinimumUpperCase(ComponentName who, int userHandle) {
   1537         if (!mHasFeature) {
   1538             return 0;
   1539         }
   1540         enforceCrossUserPermission(userHandle);
   1541         synchronized (this) {
   1542             int length = 0;
   1543 
   1544             if (who != null) {
   1545                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1546                 return admin != null ? admin.minimumPasswordUpperCase : length;
   1547             }
   1548 
   1549             DevicePolicyData policy = getUserData(userHandle);
   1550             final int N = policy.mAdminList.size();
   1551             for (int i=0; i<N; i++) {
   1552                 ActiveAdmin admin = policy.mAdminList.get(i);
   1553                 if (length < admin.minimumPasswordUpperCase) {
   1554                     length = admin.minimumPasswordUpperCase;
   1555                 }
   1556             }
   1557             return length;
   1558         }
   1559     }
   1560 
   1561     public void setPasswordMinimumLowerCase(ComponentName who, int length, int userHandle) {
   1562         enforceCrossUserPermission(userHandle);
   1563         synchronized (this) {
   1564             if (who == null) {
   1565                 throw new NullPointerException("ComponentName is null");
   1566             }
   1567             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1568                     DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
   1569             if (ap.minimumPasswordLowerCase != length) {
   1570                 ap.minimumPasswordLowerCase = length;
   1571                 saveSettingsLocked(userHandle);
   1572             }
   1573         }
   1574     }
   1575 
   1576     public int getPasswordMinimumLowerCase(ComponentName who, int userHandle) {
   1577         if (!mHasFeature) {
   1578             return 0;
   1579         }
   1580         enforceCrossUserPermission(userHandle);
   1581         synchronized (this) {
   1582             int length = 0;
   1583 
   1584             if (who != null) {
   1585                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1586                 return admin != null ? admin.minimumPasswordLowerCase : length;
   1587             }
   1588 
   1589             DevicePolicyData policy = getUserData(userHandle);
   1590             final int N = policy.mAdminList.size();
   1591             for (int i=0; i<N; i++) {
   1592                 ActiveAdmin admin = policy.mAdminList.get(i);
   1593                 if (length < admin.minimumPasswordLowerCase) {
   1594                     length = admin.minimumPasswordLowerCase;
   1595                 }
   1596             }
   1597             return length;
   1598         }
   1599     }
   1600 
   1601     public void setPasswordMinimumLetters(ComponentName who, int length, int userHandle) {
   1602         if (!mHasFeature) {
   1603             return;
   1604         }
   1605         enforceCrossUserPermission(userHandle);
   1606         synchronized (this) {
   1607             if (who == null) {
   1608                 throw new NullPointerException("ComponentName is null");
   1609             }
   1610             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1611                     DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
   1612             if (ap.minimumPasswordLetters != length) {
   1613                 ap.minimumPasswordLetters = length;
   1614                 saveSettingsLocked(userHandle);
   1615             }
   1616         }
   1617     }
   1618 
   1619     public int getPasswordMinimumLetters(ComponentName who, int userHandle) {
   1620         if (!mHasFeature) {
   1621             return 0;
   1622         }
   1623         enforceCrossUserPermission(userHandle);
   1624         synchronized (this) {
   1625             int length = 0;
   1626 
   1627             if (who != null) {
   1628                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1629                 return admin != null ? admin.minimumPasswordLetters : length;
   1630             }
   1631 
   1632             DevicePolicyData policy = getUserData(userHandle);
   1633             final int N = policy.mAdminList.size();
   1634             for (int i=0; i<N; i++) {
   1635                 ActiveAdmin admin = policy.mAdminList.get(i);
   1636                 if (length < admin.minimumPasswordLetters) {
   1637                     length = admin.minimumPasswordLetters;
   1638                 }
   1639             }
   1640             return length;
   1641         }
   1642     }
   1643 
   1644     public void setPasswordMinimumNumeric(ComponentName who, int length, int userHandle) {
   1645         if (!mHasFeature) {
   1646             return;
   1647         }
   1648         enforceCrossUserPermission(userHandle);
   1649         synchronized (this) {
   1650             if (who == null) {
   1651                 throw new NullPointerException("ComponentName is null");
   1652             }
   1653             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1654                     DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
   1655             if (ap.minimumPasswordNumeric != length) {
   1656                 ap.minimumPasswordNumeric = length;
   1657                 saveSettingsLocked(userHandle);
   1658             }
   1659         }
   1660     }
   1661 
   1662     public int getPasswordMinimumNumeric(ComponentName who, int userHandle) {
   1663         if (!mHasFeature) {
   1664             return 0;
   1665         }
   1666         enforceCrossUserPermission(userHandle);
   1667         synchronized (this) {
   1668             int length = 0;
   1669 
   1670             if (who != null) {
   1671                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1672                 return admin != null ? admin.minimumPasswordNumeric : length;
   1673             }
   1674 
   1675             DevicePolicyData policy = getUserData(userHandle);
   1676             final int N = policy.mAdminList.size();
   1677             for (int i = 0; i < N; i++) {
   1678                 ActiveAdmin admin = policy.mAdminList.get(i);
   1679                 if (length < admin.minimumPasswordNumeric) {
   1680                     length = admin.minimumPasswordNumeric;
   1681                 }
   1682             }
   1683             return length;
   1684         }
   1685     }
   1686 
   1687     public void setPasswordMinimumSymbols(ComponentName who, int length, int userHandle) {
   1688         if (!mHasFeature) {
   1689             return;
   1690         }
   1691         enforceCrossUserPermission(userHandle);
   1692         synchronized (this) {
   1693             if (who == null) {
   1694                 throw new NullPointerException("ComponentName is null");
   1695             }
   1696             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1697                     DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
   1698             if (ap.minimumPasswordSymbols != length) {
   1699                 ap.minimumPasswordSymbols = length;
   1700                 saveSettingsLocked(userHandle);
   1701             }
   1702         }
   1703     }
   1704 
   1705     public int getPasswordMinimumSymbols(ComponentName who, int userHandle) {
   1706         if (!mHasFeature) {
   1707             return 0;
   1708         }
   1709         enforceCrossUserPermission(userHandle);
   1710         synchronized (this) {
   1711             int length = 0;
   1712 
   1713             if (who != null) {
   1714                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1715                 return admin != null ? admin.minimumPasswordSymbols : length;
   1716             }
   1717 
   1718             DevicePolicyData policy = getUserData(userHandle);
   1719             final int N = policy.mAdminList.size();
   1720             for  (int i=0; i<N; i++) {
   1721                 ActiveAdmin admin = policy.mAdminList.get(i);
   1722                 if (length < admin.minimumPasswordSymbols) {
   1723                     length = admin.minimumPasswordSymbols;
   1724                 }
   1725             }
   1726             return length;
   1727         }
   1728     }
   1729 
   1730     public void setPasswordMinimumNonLetter(ComponentName who, int length, int userHandle) {
   1731         if (!mHasFeature) {
   1732             return;
   1733         }
   1734         enforceCrossUserPermission(userHandle);
   1735         synchronized (this) {
   1736             if (who == null) {
   1737                 throw new NullPointerException("ComponentName is null");
   1738             }
   1739             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1740                     DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
   1741             if (ap.minimumPasswordNonLetter != length) {
   1742                 ap.minimumPasswordNonLetter = length;
   1743                 saveSettingsLocked(userHandle);
   1744             }
   1745         }
   1746     }
   1747 
   1748     public int getPasswordMinimumNonLetter(ComponentName who, int userHandle) {
   1749         if (!mHasFeature) {
   1750             return 0;
   1751         }
   1752         enforceCrossUserPermission(userHandle);
   1753         synchronized (this) {
   1754             int length = 0;
   1755 
   1756             if (who != null) {
   1757                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1758                 return admin != null ? admin.minimumPasswordNonLetter : length;
   1759             }
   1760 
   1761             DevicePolicyData policy = getUserData(userHandle);
   1762             final int N = policy.mAdminList.size();
   1763             for (int i=0; i<N; i++) {
   1764                 ActiveAdmin admin = policy.mAdminList.get(i);
   1765                 if (length < admin.minimumPasswordNonLetter) {
   1766                     length = admin.minimumPasswordNonLetter;
   1767                 }
   1768             }
   1769             return length;
   1770         }
   1771     }
   1772 
   1773     public boolean isActivePasswordSufficient(int userHandle) {
   1774         if (!mHasFeature) {
   1775             return true;
   1776         }
   1777         enforceCrossUserPermission(userHandle);
   1778         synchronized (this) {
   1779             DevicePolicyData policy = getUserData(userHandle);
   1780             // This API can only be called by an active device admin,
   1781             // so try to retrieve it to check that the caller is one.
   1782             getActiveAdminForCallerLocked(null,
   1783                     DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
   1784             if (policy.mActivePasswordQuality < getPasswordQuality(null, userHandle)
   1785                     || policy.mActivePasswordLength < getPasswordMinimumLength(null, userHandle)) {
   1786                 return false;
   1787             }
   1788             if (policy.mActivePasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
   1789                 return true;
   1790             }
   1791             return policy.mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null, userHandle)
   1792                     && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null, userHandle)
   1793                     && policy.mActivePasswordLetters >= getPasswordMinimumLetters(null, userHandle)
   1794                     && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(null, userHandle)
   1795                     && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(null, userHandle)
   1796                     && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null, userHandle);
   1797         }
   1798     }
   1799 
   1800     public int getCurrentFailedPasswordAttempts(int userHandle) {
   1801         enforceCrossUserPermission(userHandle);
   1802         synchronized (this) {
   1803             // This API can only be called by an active device admin,
   1804             // so try to retrieve it to check that the caller is one.
   1805             getActiveAdminForCallerLocked(null,
   1806                     DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
   1807             return getUserData(userHandle).mFailedPasswordAttempts;
   1808         }
   1809     }
   1810 
   1811     public void setMaximumFailedPasswordsForWipe(ComponentName who, int num, int userHandle) {
   1812         if (!mHasFeature) {
   1813             return;
   1814         }
   1815         enforceCrossUserPermission(userHandle);
   1816         synchronized (this) {
   1817             // This API can only be called by an active device admin,
   1818             // so try to retrieve it to check that the caller is one.
   1819             getActiveAdminForCallerLocked(who,
   1820                     DeviceAdminInfo.USES_POLICY_WIPE_DATA);
   1821             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1822                     DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
   1823             if (ap.maximumFailedPasswordsForWipe != num) {
   1824                 ap.maximumFailedPasswordsForWipe = num;
   1825                 saveSettingsLocked(userHandle);
   1826             }
   1827         }
   1828     }
   1829 
   1830     public int getMaximumFailedPasswordsForWipe(ComponentName who, int userHandle) {
   1831         if (!mHasFeature) {
   1832             return 0;
   1833         }
   1834         enforceCrossUserPermission(userHandle);
   1835         synchronized (this) {
   1836             DevicePolicyData policy = getUserData(userHandle);
   1837             int count = 0;
   1838 
   1839             if (who != null) {
   1840                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   1841                 return admin != null ? admin.maximumFailedPasswordsForWipe : count;
   1842             }
   1843 
   1844             final int N = policy.mAdminList.size();
   1845             for  (int i=0; i<N; i++) {
   1846                 ActiveAdmin admin = policy.mAdminList.get(i);
   1847                 if (count == 0) {
   1848                     count = admin.maximumFailedPasswordsForWipe;
   1849                 } else if (admin.maximumFailedPasswordsForWipe != 0
   1850                         && count > admin.maximumFailedPasswordsForWipe) {
   1851                     count = admin.maximumFailedPasswordsForWipe;
   1852                 }
   1853             }
   1854             return count;
   1855         }
   1856     }
   1857 
   1858     public boolean resetPassword(String password, int flags, int userHandle) {
   1859         if (!mHasFeature) {
   1860             return false;
   1861         }
   1862         enforceCrossUserPermission(userHandle);
   1863         int quality;
   1864         synchronized (this) {
   1865             // This API can only be called by an active device admin,
   1866             // so try to retrieve it to check that the caller is one.
   1867             getActiveAdminForCallerLocked(null,
   1868                     DeviceAdminInfo.USES_POLICY_RESET_PASSWORD);
   1869             quality = getPasswordQuality(null, userHandle);
   1870             if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
   1871                 int realQuality = LockPatternUtils.computePasswordQuality(password);
   1872                 if (realQuality < quality
   1873                         && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
   1874                     Slog.w(TAG, "resetPassword: password quality 0x"
   1875                             + Integer.toHexString(realQuality)
   1876                             + " does not meet required quality 0x"
   1877                             + Integer.toHexString(quality));
   1878                     return false;
   1879                 }
   1880                 quality = Math.max(realQuality, quality);
   1881             }
   1882             int length = getPasswordMinimumLength(null, userHandle);
   1883             if (password.length() < length) {
   1884                 Slog.w(TAG, "resetPassword: password length " + password.length()
   1885                         + " does not meet required length " + length);
   1886                 return false;
   1887             }
   1888             if (quality == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
   1889                 int letters = 0;
   1890                 int uppercase = 0;
   1891                 int lowercase = 0;
   1892                 int numbers = 0;
   1893                 int symbols = 0;
   1894                 int nonletter = 0;
   1895                 for (int i = 0; i < password.length(); i++) {
   1896                     char c = password.charAt(i);
   1897                     if (c >= 'A' && c <= 'Z') {
   1898                         letters++;
   1899                         uppercase++;
   1900                     } else if (c >= 'a' && c <= 'z') {
   1901                         letters++;
   1902                         lowercase++;
   1903                     } else if (c >= '0' && c <= '9') {
   1904                         numbers++;
   1905                         nonletter++;
   1906                     } else {
   1907                         symbols++;
   1908                         nonletter++;
   1909                     }
   1910                 }
   1911                 int neededLetters = getPasswordMinimumLetters(null, userHandle);
   1912                 if(letters < neededLetters) {
   1913                     Slog.w(TAG, "resetPassword: number of letters " + letters
   1914                             + " does not meet required number of letters " + neededLetters);
   1915                     return false;
   1916                 }
   1917                 int neededNumbers = getPasswordMinimumNumeric(null, userHandle);
   1918                 if (numbers < neededNumbers) {
   1919                     Slog.w(TAG, "resetPassword: number of numerical digits " + numbers
   1920                             + " does not meet required number of numerical digits "
   1921                             + neededNumbers);
   1922                     return false;
   1923                 }
   1924                 int neededLowerCase = getPasswordMinimumLowerCase(null, userHandle);
   1925                 if (lowercase < neededLowerCase) {
   1926                     Slog.w(TAG, "resetPassword: number of lowercase letters " + lowercase
   1927                             + " does not meet required number of lowercase letters "
   1928                             + neededLowerCase);
   1929                     return false;
   1930                 }
   1931                 int neededUpperCase = getPasswordMinimumUpperCase(null, userHandle);
   1932                 if (uppercase < neededUpperCase) {
   1933                     Slog.w(TAG, "resetPassword: number of uppercase letters " + uppercase
   1934                             + " does not meet required number of uppercase letters "
   1935                             + neededUpperCase);
   1936                     return false;
   1937                 }
   1938                 int neededSymbols = getPasswordMinimumSymbols(null, userHandle);
   1939                 if (symbols < neededSymbols) {
   1940                     Slog.w(TAG, "resetPassword: number of special symbols " + symbols
   1941                             + " does not meet required number of special symbols " + neededSymbols);
   1942                     return false;
   1943                 }
   1944                 int neededNonLetter = getPasswordMinimumNonLetter(null, userHandle);
   1945                 if (nonletter < neededNonLetter) {
   1946                     Slog.w(TAG, "resetPassword: number of non-letter characters " + nonletter
   1947                             + " does not meet required number of non-letter characters "
   1948                             + neededNonLetter);
   1949                     return false;
   1950                 }
   1951             }
   1952         }
   1953 
   1954         int callingUid = Binder.getCallingUid();
   1955         DevicePolicyData policy = getUserData(userHandle);
   1956         if (policy.mPasswordOwner >= 0 && policy.mPasswordOwner != callingUid) {
   1957             Slog.w(TAG, "resetPassword: already set by another uid and not entered by user");
   1958             return false;
   1959         }
   1960 
   1961         // Don't do this with the lock held, because it is going to call
   1962         // back in to the service.
   1963         long ident = Binder.clearCallingIdentity();
   1964         try {
   1965             LockPatternUtils utils = new LockPatternUtils(mContext);
   1966             utils.saveLockPassword(password, quality, false, userHandle);
   1967             synchronized (this) {
   1968                 int newOwner = (flags&DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY)
   1969                         != 0 ? callingUid : -1;
   1970                 if (policy.mPasswordOwner != newOwner) {
   1971                     policy.mPasswordOwner = newOwner;
   1972                     saveSettingsLocked(userHandle);
   1973                 }
   1974             }
   1975         } finally {
   1976             Binder.restoreCallingIdentity(ident);
   1977         }
   1978 
   1979         return true;
   1980     }
   1981 
   1982     public void setMaximumTimeToLock(ComponentName who, long timeMs, int userHandle) {
   1983         if (!mHasFeature) {
   1984             return;
   1985         }
   1986         enforceCrossUserPermission(userHandle);
   1987         synchronized (this) {
   1988             if (who == null) {
   1989                 throw new NullPointerException("ComponentName is null");
   1990             }
   1991             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   1992                     DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
   1993             if (ap.maximumTimeToUnlock != timeMs) {
   1994                 ap.maximumTimeToUnlock = timeMs;
   1995                 saveSettingsLocked(userHandle);
   1996                 updateMaximumTimeToLockLocked(getUserData(userHandle));
   1997             }
   1998         }
   1999     }
   2000 
   2001     void updateMaximumTimeToLockLocked(DevicePolicyData policy) {
   2002         long timeMs = getMaximumTimeToLock(null, policy.mUserHandle);
   2003         if (policy.mLastMaximumTimeToLock == timeMs) {
   2004             return;
   2005         }
   2006 
   2007         long ident = Binder.clearCallingIdentity();
   2008         try {
   2009             if (timeMs <= 0) {
   2010                 timeMs = Integer.MAX_VALUE;
   2011             } else {
   2012                 // Make sure KEEP_SCREEN_ON is disabled, since that
   2013                 // would allow bypassing of the maximum time to lock.
   2014                 Settings.Global.putInt(mContext.getContentResolver(),
   2015                         Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
   2016             }
   2017 
   2018             policy.mLastMaximumTimeToLock = timeMs;
   2019 
   2020             try {
   2021                 getIPowerManager().setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs);
   2022             } catch (RemoteException e) {
   2023                 Slog.w(TAG, "Failure talking with power manager", e);
   2024             }
   2025         } finally {
   2026             Binder.restoreCallingIdentity(ident);
   2027         }
   2028     }
   2029 
   2030     public long getMaximumTimeToLock(ComponentName who, int userHandle) {
   2031         if (!mHasFeature) {
   2032             return 0;
   2033         }
   2034         enforceCrossUserPermission(userHandle);
   2035         synchronized (this) {
   2036             long time = 0;
   2037 
   2038             if (who != null) {
   2039                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   2040                 return admin != null ? admin.maximumTimeToUnlock : time;
   2041             }
   2042 
   2043             DevicePolicyData policy = getUserData(userHandle);
   2044             final int N = policy.mAdminList.size();
   2045             for  (int i=0; i<N; i++) {
   2046                 ActiveAdmin admin = policy.mAdminList.get(i);
   2047                 if (time == 0) {
   2048                     time = admin.maximumTimeToUnlock;
   2049                 } else if (admin.maximumTimeToUnlock != 0
   2050                         && time > admin.maximumTimeToUnlock) {
   2051                     time = admin.maximumTimeToUnlock;
   2052                 }
   2053             }
   2054             return time;
   2055         }
   2056     }
   2057 
   2058     public void lockNow() {
   2059         if (!mHasFeature) {
   2060             return;
   2061         }
   2062         synchronized (this) {
   2063             // This API can only be called by an active device admin,
   2064             // so try to retrieve it to check that the caller is one.
   2065             getActiveAdminForCallerLocked(null,
   2066                     DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
   2067             lockNowUnchecked();
   2068         }
   2069     }
   2070 
   2071     private void lockNowUnchecked() {
   2072         long ident = Binder.clearCallingIdentity();
   2073         try {
   2074             // Power off the display
   2075             getIPowerManager().goToSleep(SystemClock.uptimeMillis(),
   2076                     PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN);
   2077             // Ensure the device is locked
   2078             getWindowManager().lockNow(null);
   2079         } catch (RemoteException e) {
   2080         } finally {
   2081             Binder.restoreCallingIdentity(ident);
   2082         }
   2083     }
   2084 
   2085     private boolean isExtStorageEncrypted() {
   2086         String state = SystemProperties.get("vold.decrypt");
   2087         return !"".equals(state);
   2088     }
   2089 
   2090     public boolean installCaCert(byte[] certBuffer) throws RemoteException {
   2091         mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
   2092         KeyChainConnection keyChainConnection = null;
   2093         byte[] pemCert;
   2094         try {
   2095             X509Certificate cert = parseCert(certBuffer);
   2096             pemCert =  Credentials.convertToPem(cert);
   2097         } catch (CertificateException ce) {
   2098             Log.e(TAG, "Problem converting cert", ce);
   2099             return false;
   2100         } catch (IOException ioe) {
   2101             Log.e(TAG, "Problem reading cert", ioe);
   2102             return false;
   2103         }
   2104         try {
   2105             keyChainConnection = KeyChain.bind(mContext);
   2106             try {
   2107                 keyChainConnection.getService().installCaCertificate(pemCert);
   2108                 return true;
   2109             } finally {
   2110                 if (keyChainConnection != null) {
   2111                     keyChainConnection.close();
   2112                     keyChainConnection = null;
   2113                 }
   2114             }
   2115         } catch (InterruptedException e1) {
   2116             Log.w(TAG, "installCaCertsToKeyChain(): ", e1);
   2117             Thread.currentThread().interrupt();
   2118         }
   2119         return false;
   2120     }
   2121 
   2122     private static X509Certificate parseCert(byte[] certBuffer)
   2123             throws CertificateException, IOException {
   2124         CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
   2125         return (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(
   2126                 certBuffer));
   2127     }
   2128 
   2129     public void uninstallCaCert(final byte[] certBuffer) {
   2130         mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
   2131         TrustedCertificateStore certStore = new TrustedCertificateStore();
   2132         String alias = null;
   2133         try {
   2134             X509Certificate cert = parseCert(certBuffer);
   2135             alias = certStore.getCertificateAlias(cert);
   2136         } catch (CertificateException ce) {
   2137             Log.e(TAG, "Problem creating X509Certificate", ce);
   2138             return;
   2139         } catch (IOException ioe) {
   2140             Log.e(TAG, "Problem reading certificate", ioe);
   2141             return;
   2142         }
   2143         try {
   2144             KeyChainConnection keyChainConnection = KeyChain.bind(mContext);
   2145             IKeyChainService service = keyChainConnection.getService();
   2146             try {
   2147                 service.deleteCaCertificate(alias);
   2148             } catch (RemoteException e) {
   2149                 Log.e(TAG, "from CaCertUninstaller: ", e);
   2150             } finally {
   2151                 keyChainConnection.close();
   2152                 keyChainConnection = null;
   2153             }
   2154         } catch (InterruptedException ie) {
   2155             Log.w(TAG, "CaCertUninstaller: ", ie);
   2156             Thread.currentThread().interrupt();
   2157         }
   2158     }
   2159 
   2160     void wipeDataLocked(int flags) {
   2161         // If the SD card is encrypted and non-removable, we have to force a wipe.
   2162         boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
   2163         boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0;
   2164 
   2165         // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
   2166         if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
   2167             Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
   2168             intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true);
   2169             intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
   2170             mWakeLock.acquire(10000);
   2171             mContext.startService(intent);
   2172         } else {
   2173             try {
   2174                 RecoverySystem.rebootWipeUserData(mContext);
   2175             } catch (IOException e) {
   2176                 Slog.w(TAG, "Failed requesting data wipe", e);
   2177             }
   2178         }
   2179     }
   2180 
   2181     public void wipeData(int flags, final int userHandle) {
   2182         if (!mHasFeature) {
   2183             return;
   2184         }
   2185         enforceCrossUserPermission(userHandle);
   2186         synchronized (this) {
   2187             // This API can only be called by an active device admin,
   2188             // so try to retrieve it to check that the caller is one.
   2189             getActiveAdminForCallerLocked(null,
   2190                     DeviceAdminInfo.USES_POLICY_WIPE_DATA);
   2191             long ident = Binder.clearCallingIdentity();
   2192             try {
   2193                 wipeDeviceOrUserLocked(flags, userHandle);
   2194             } finally {
   2195                 Binder.restoreCallingIdentity(ident);
   2196             }
   2197         }
   2198     }
   2199 
   2200     private void wipeDeviceOrUserLocked(int flags, final int userHandle) {
   2201         if (userHandle == UserHandle.USER_OWNER) {
   2202             wipeDataLocked(flags);
   2203         } else {
   2204             lockNowUnchecked();
   2205             mHandler.post(new Runnable() {
   2206                 public void run() {
   2207                     try {
   2208                         ActivityManagerNative.getDefault().switchUser(UserHandle.USER_OWNER);
   2209                         ((UserManager) mContext.getSystemService(Context.USER_SERVICE))
   2210                                 .removeUser(userHandle);
   2211                     } catch (RemoteException re) {
   2212                         // Shouldn't happen
   2213                     }
   2214                 }
   2215             });
   2216         }
   2217     }
   2218 
   2219     public void getRemoveWarning(ComponentName comp, final RemoteCallback result, int userHandle) {
   2220         if (!mHasFeature) {
   2221             return;
   2222         }
   2223         enforceCrossUserPermission(userHandle);
   2224         mContext.enforceCallingOrSelfPermission(
   2225                 android.Manifest.permission.BIND_DEVICE_ADMIN, null);
   2226 
   2227         synchronized (this) {
   2228             ActiveAdmin admin = getActiveAdminUncheckedLocked(comp, userHandle);
   2229             if (admin == null) {
   2230                 try {
   2231                     result.sendResult(null);
   2232                 } catch (RemoteException e) {
   2233                 }
   2234                 return;
   2235             }
   2236             Intent intent = new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED);
   2237             intent.setComponent(admin.info.getComponent());
   2238             mContext.sendOrderedBroadcastAsUser(intent, new UserHandle(userHandle),
   2239                     null, new BroadcastReceiver() {
   2240                 @Override
   2241                 public void onReceive(Context context, Intent intent) {
   2242                     try {
   2243                         result.sendResult(getResultExtras(false));
   2244                     } catch (RemoteException e) {
   2245                     }
   2246                 }
   2247             }, null, Activity.RESULT_OK, null, null);
   2248         }
   2249     }
   2250 
   2251     public void setActivePasswordState(int quality, int length, int letters, int uppercase,
   2252             int lowercase, int numbers, int symbols, int nonletter, int userHandle) {
   2253         if (!mHasFeature) {
   2254             return;
   2255         }
   2256         enforceCrossUserPermission(userHandle);
   2257         mContext.enforceCallingOrSelfPermission(
   2258                 android.Manifest.permission.BIND_DEVICE_ADMIN, null);
   2259         DevicePolicyData p = getUserData(userHandle);
   2260 
   2261         validateQualityConstant(quality);
   2262 
   2263         synchronized (this) {
   2264             if (p.mActivePasswordQuality != quality || p.mActivePasswordLength != length
   2265                     || p.mFailedPasswordAttempts != 0 || p.mActivePasswordLetters != letters
   2266                     || p.mActivePasswordUpperCase != uppercase
   2267                     || p.mActivePasswordLowerCase != lowercase || p.mActivePasswordNumeric != numbers
   2268                     || p.mActivePasswordSymbols != symbols || p.mActivePasswordNonLetter != nonletter) {
   2269                 long ident = Binder.clearCallingIdentity();
   2270                 try {
   2271                     p.mActivePasswordQuality = quality;
   2272                     p.mActivePasswordLength = length;
   2273                     p.mActivePasswordLetters = letters;
   2274                     p.mActivePasswordLowerCase = lowercase;
   2275                     p.mActivePasswordUpperCase = uppercase;
   2276                     p.mActivePasswordNumeric = numbers;
   2277                     p.mActivePasswordSymbols = symbols;
   2278                     p.mActivePasswordNonLetter = nonletter;
   2279                     p.mFailedPasswordAttempts = 0;
   2280                     saveSettingsLocked(userHandle);
   2281                     updatePasswordExpirationsLocked(userHandle);
   2282                     setExpirationAlarmCheckLocked(mContext, p);
   2283                     sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
   2284                             DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle);
   2285                 } finally {
   2286                     Binder.restoreCallingIdentity(ident);
   2287                 }
   2288             }
   2289         }
   2290     }
   2291 
   2292     /**
   2293      * Called any time the device password is updated.  Resets all password expiration clocks.
   2294      */
   2295     private void updatePasswordExpirationsLocked(int userHandle) {
   2296         DevicePolicyData policy = getUserData(userHandle);
   2297         final int N = policy.mAdminList.size();
   2298         if (N > 0) {
   2299             for (int i=0; i<N; i++) {
   2300                 ActiveAdmin admin = policy.mAdminList.get(i);
   2301                 if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) {
   2302                     long timeout = admin.passwordExpirationTimeout;
   2303                     long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
   2304                     admin.passwordExpirationDate = expiration;
   2305                 }
   2306             }
   2307             saveSettingsLocked(userHandle);
   2308         }
   2309     }
   2310 
   2311     public void reportFailedPasswordAttempt(int userHandle) {
   2312         enforceCrossUserPermission(userHandle);
   2313         mContext.enforceCallingOrSelfPermission(
   2314                 android.Manifest.permission.BIND_DEVICE_ADMIN, null);
   2315 
   2316         synchronized (this) {
   2317             DevicePolicyData policy = getUserData(userHandle);
   2318             long ident = Binder.clearCallingIdentity();
   2319             try {
   2320                 policy.mFailedPasswordAttempts++;
   2321                 saveSettingsLocked(userHandle);
   2322                 if (mHasFeature) {
   2323                     int max = getMaximumFailedPasswordsForWipe(null, userHandle);
   2324                     if (max > 0 && policy.mFailedPasswordAttempts >= max) {
   2325                         wipeDeviceOrUserLocked(0, userHandle);
   2326                     }
   2327                     sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_FAILED,
   2328                             DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
   2329                 }
   2330             } finally {
   2331                 Binder.restoreCallingIdentity(ident);
   2332             }
   2333         }
   2334     }
   2335 
   2336     public void reportSuccessfulPasswordAttempt(int userHandle) {
   2337         enforceCrossUserPermission(userHandle);
   2338         mContext.enforceCallingOrSelfPermission(
   2339                 android.Manifest.permission.BIND_DEVICE_ADMIN, null);
   2340 
   2341         synchronized (this) {
   2342             DevicePolicyData policy = getUserData(userHandle);
   2343             if (policy.mFailedPasswordAttempts != 0 || policy.mPasswordOwner >= 0) {
   2344                 long ident = Binder.clearCallingIdentity();
   2345                 try {
   2346                     policy.mFailedPasswordAttempts = 0;
   2347                     policy.mPasswordOwner = -1;
   2348                     saveSettingsLocked(userHandle);
   2349                     if (mHasFeature) {
   2350                         sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED,
   2351                                 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
   2352                     }
   2353                 } finally {
   2354                     Binder.restoreCallingIdentity(ident);
   2355                 }
   2356             }
   2357         }
   2358     }
   2359 
   2360     public ComponentName setGlobalProxy(ComponentName who, String proxySpec,
   2361             String exclusionList, int userHandle) {
   2362         if (!mHasFeature) {
   2363             return null;
   2364         }
   2365         enforceCrossUserPermission(userHandle);
   2366         synchronized(this) {
   2367             if (who == null) {
   2368                 throw new NullPointerException("ComponentName is null");
   2369             }
   2370 
   2371             // Only check if owner has set global proxy. We don't allow other users to set it.
   2372             DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
   2373             ActiveAdmin admin = getActiveAdminForCallerLocked(who,
   2374                     DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
   2375 
   2376             // Scan through active admins and find if anyone has already
   2377             // set the global proxy.
   2378             Set<ComponentName> compSet = policy.mAdminMap.keySet();
   2379             for  (ComponentName component : compSet) {
   2380                 ActiveAdmin ap = policy.mAdminMap.get(component);
   2381                 if ((ap.specifiesGlobalProxy) && (!component.equals(who))) {
   2382                     // Another admin already sets the global proxy
   2383                     // Return it to the caller.
   2384                     return component;
   2385                 }
   2386             }
   2387 
   2388             // If the user is not the owner, don't set the global proxy. Fail silently.
   2389             if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
   2390                 Slog.w(TAG, "Only the owner is allowed to set the global proxy. User "
   2391                         + userHandle + " is not permitted.");
   2392                 return null;
   2393             }
   2394             if (proxySpec == null) {
   2395                 admin.specifiesGlobalProxy = false;
   2396                 admin.globalProxySpec = null;
   2397                 admin.globalProxyExclusionList = null;
   2398             } else {
   2399 
   2400                 admin.specifiesGlobalProxy = true;
   2401                 admin.globalProxySpec = proxySpec;
   2402                 admin.globalProxyExclusionList = exclusionList;
   2403             }
   2404 
   2405             // Reset the global proxy accordingly
   2406             // Do this using system permissions, as apps cannot write to secure settings
   2407             long origId = Binder.clearCallingIdentity();
   2408             resetGlobalProxyLocked(policy);
   2409             Binder.restoreCallingIdentity(origId);
   2410             return null;
   2411         }
   2412     }
   2413 
   2414     public ComponentName getGlobalProxyAdmin(int userHandle) {
   2415         if (!mHasFeature) {
   2416             return null;
   2417         }
   2418         enforceCrossUserPermission(userHandle);
   2419         synchronized(this) {
   2420             DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
   2421             // Scan through active admins and find if anyone has already
   2422             // set the global proxy.
   2423             final int N = policy.mAdminList.size();
   2424             for (int i = 0; i < N; i++) {
   2425                 ActiveAdmin ap = policy.mAdminList.get(i);
   2426                 if (ap.specifiesGlobalProxy) {
   2427                     // Device admin sets the global proxy
   2428                     // Return it to the caller.
   2429                     return ap.info.getComponent();
   2430                 }
   2431             }
   2432         }
   2433         // No device admin sets the global proxy.
   2434         return null;
   2435     }
   2436 
   2437     private void resetGlobalProxyLocked(DevicePolicyData policy) {
   2438         final int N = policy.mAdminList.size();
   2439         for (int i = 0; i < N; i++) {
   2440             ActiveAdmin ap = policy.mAdminList.get(i);
   2441             if (ap.specifiesGlobalProxy) {
   2442                 saveGlobalProxyLocked(ap.globalProxySpec, ap.globalProxyExclusionList);
   2443                 return;
   2444             }
   2445         }
   2446         // No device admins defining global proxies - reset global proxy settings to none
   2447         saveGlobalProxyLocked(null, null);
   2448     }
   2449 
   2450     private void saveGlobalProxyLocked(String proxySpec, String exclusionList) {
   2451         if (exclusionList == null) {
   2452             exclusionList = "";
   2453         }
   2454         if (proxySpec == null) {
   2455             proxySpec = "";
   2456         }
   2457         // Remove white spaces
   2458         proxySpec = proxySpec.trim();
   2459         String data[] = proxySpec.split(":");
   2460         int proxyPort = 8080;
   2461         if (data.length > 1) {
   2462             try {
   2463                 proxyPort = Integer.parseInt(data[1]);
   2464             } catch (NumberFormatException e) {}
   2465         }
   2466         exclusionList = exclusionList.trim();
   2467         ContentResolver res = mContext.getContentResolver();
   2468 
   2469         ProxyProperties proxyProperties = new ProxyProperties(data[0], proxyPort, exclusionList);
   2470         if (!proxyProperties.isValid()) {
   2471             Slog.e(TAG, "Invalid proxy properties, ignoring: " + proxyProperties.toString());
   2472             return;
   2473         }
   2474         Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, data[0]);
   2475         Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, proxyPort);
   2476         Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
   2477                 exclusionList);
   2478     }
   2479 
   2480     /**
   2481      * Set the storage encryption request for a single admin.  Returns the new total request
   2482      * status (for all admins).
   2483      */
   2484     public int setStorageEncryption(ComponentName who, boolean encrypt, int userHandle) {
   2485         if (!mHasFeature) {
   2486             return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
   2487         }
   2488         enforceCrossUserPermission(userHandle);
   2489         synchronized (this) {
   2490             // Check for permissions
   2491             if (who == null) {
   2492                 throw new NullPointerException("ComponentName is null");
   2493             }
   2494             // Only owner can set storage encryption
   2495             if (userHandle != UserHandle.USER_OWNER
   2496                     || UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
   2497                 Slog.w(TAG, "Only owner is allowed to set storage encryption. User "
   2498                         + UserHandle.getCallingUserId() + " is not permitted.");
   2499                 return 0;
   2500             }
   2501 
   2502             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   2503                     DeviceAdminInfo.USES_ENCRYPTED_STORAGE);
   2504 
   2505             // Quick exit:  If the filesystem does not support encryption, we can exit early.
   2506             if (!isEncryptionSupported()) {
   2507                 return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
   2508             }
   2509 
   2510             // (1) Record the value for the admin so it's sticky
   2511             if (ap.encryptionRequested != encrypt) {
   2512                 ap.encryptionRequested = encrypt;
   2513                 saveSettingsLocked(userHandle);
   2514             }
   2515 
   2516             DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
   2517             // (2) Compute "max" for all admins
   2518             boolean newRequested = false;
   2519             final int N = policy.mAdminList.size();
   2520             for (int i = 0; i < N; i++) {
   2521                 newRequested |= policy.mAdminList.get(i).encryptionRequested;
   2522             }
   2523 
   2524             // Notify OS of new request
   2525             setEncryptionRequested(newRequested);
   2526 
   2527             // Return the new global request status
   2528             return newRequested
   2529                     ? DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE
   2530                     : DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
   2531         }
   2532     }
   2533 
   2534     /**
   2535      * Get the current storage encryption request status for a given admin, or aggregate of all
   2536      * active admins.
   2537      */
   2538     public boolean getStorageEncryption(ComponentName who, int userHandle) {
   2539         if (!mHasFeature) {
   2540             return false;
   2541         }
   2542         enforceCrossUserPermission(userHandle);
   2543         synchronized (this) {
   2544             // Check for permissions if a particular caller is specified
   2545             if (who != null) {
   2546                 // When checking for a single caller, status is based on caller's request
   2547                 ActiveAdmin ap = getActiveAdminUncheckedLocked(who, userHandle);
   2548                 return ap != null ? ap.encryptionRequested : false;
   2549             }
   2550 
   2551             // If no particular caller is specified, return the aggregate set of requests.
   2552             // This is short circuited by returning true on the first hit.
   2553             DevicePolicyData policy = getUserData(userHandle);
   2554             final int N = policy.mAdminList.size();
   2555             for (int i = 0; i < N; i++) {
   2556                 if (policy.mAdminList.get(i).encryptionRequested) {
   2557                     return true;
   2558                 }
   2559             }
   2560             return false;
   2561         }
   2562     }
   2563 
   2564     /**
   2565      * Get the current encryption status of the device.
   2566      */
   2567     public int getStorageEncryptionStatus(int userHandle) {
   2568         if (!mHasFeature) {
   2569             // Ok to return current status.
   2570         }
   2571         enforceCrossUserPermission(userHandle);
   2572         return getEncryptionStatus();
   2573     }
   2574 
   2575     /**
   2576      * Hook to low-levels:  This should report if the filesystem supports encrypted storage.
   2577      */
   2578     private boolean isEncryptionSupported() {
   2579         // Note, this can be implemented as
   2580         //   return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
   2581         // But is provided as a separate internal method if there's a faster way to do a
   2582         // simple check for supported-or-not.
   2583         return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
   2584     }
   2585 
   2586     /**
   2587      * Hook to low-levels:  Reporting the current status of encryption.
   2588      * @return A value such as {@link DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED} or
   2589      * {@link DevicePolicyManager#ENCRYPTION_STATUS_INACTIVE} or
   2590      * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE}.
   2591      */
   2592     private int getEncryptionStatus() {
   2593         String status = SystemProperties.get("ro.crypto.state", "unsupported");
   2594         if ("encrypted".equalsIgnoreCase(status)) {
   2595             return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
   2596         } else if ("unencrypted".equalsIgnoreCase(status)) {
   2597             return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
   2598         } else {
   2599             return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
   2600         }
   2601     }
   2602 
   2603     /**
   2604      * Hook to low-levels:  If needed, record the new admin setting for encryption.
   2605      */
   2606     private void setEncryptionRequested(boolean encrypt) {
   2607     }
   2608 
   2609     /**
   2610      * The system property used to share the state of the camera. The native camera service
   2611      * is expected to read this property and act accordingly.
   2612      */
   2613     public static final String SYSTEM_PROP_DISABLE_CAMERA = "sys.secpolicy.camera.disabled";
   2614 
   2615     /**
   2616      * Disables all device cameras according to the specified admin.
   2617      */
   2618     public void setCameraDisabled(ComponentName who, boolean disabled, int userHandle) {
   2619         if (!mHasFeature) {
   2620             return;
   2621         }
   2622         enforceCrossUserPermission(userHandle);
   2623         synchronized (this) {
   2624             if (who == null) {
   2625                 throw new NullPointerException("ComponentName is null");
   2626             }
   2627             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   2628                     DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA);
   2629             if (ap.disableCamera != disabled) {
   2630                 ap.disableCamera = disabled;
   2631                 saveSettingsLocked(userHandle);
   2632             }
   2633             syncDeviceCapabilitiesLocked(getUserData(userHandle));
   2634         }
   2635     }
   2636 
   2637     /**
   2638      * Gets whether or not all device cameras are disabled for a given admin, or disabled for any
   2639      * active admins.
   2640      */
   2641     public boolean getCameraDisabled(ComponentName who, int userHandle) {
   2642         if (!mHasFeature) {
   2643             return false;
   2644         }
   2645         synchronized (this) {
   2646             if (who != null) {
   2647                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   2648                 return (admin != null) ? admin.disableCamera : false;
   2649             }
   2650 
   2651             DevicePolicyData policy = getUserData(userHandle);
   2652             // Determine whether or not the device camera is disabled for any active admins.
   2653             final int N = policy.mAdminList.size();
   2654             for (int i = 0; i < N; i++) {
   2655                 ActiveAdmin admin = policy.mAdminList.get(i);
   2656                 if (admin.disableCamera) {
   2657                     return true;
   2658                 }
   2659             }
   2660             return false;
   2661         }
   2662     }
   2663 
   2664     /**
   2665      * Selectively disable keyguard features.
   2666      */
   2667     public void setKeyguardDisabledFeatures(ComponentName who, int which, int userHandle) {
   2668         if (!mHasFeature) {
   2669             return;
   2670         }
   2671         enforceCrossUserPermission(userHandle);
   2672         synchronized (this) {
   2673             if (who == null) {
   2674                 throw new NullPointerException("ComponentName is null");
   2675             }
   2676             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
   2677                     DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
   2678             if (ap.disabledKeyguardFeatures != which) {
   2679                 ap.disabledKeyguardFeatures = which;
   2680                 saveSettingsLocked(userHandle);
   2681             }
   2682             syncDeviceCapabilitiesLocked(getUserData(userHandle));
   2683         }
   2684     }
   2685 
   2686     /**
   2687      * Gets the disabled state for features in keyguard for the given admin,
   2688      * or the aggregate of all active admins if who is null.
   2689      */
   2690     public int getKeyguardDisabledFeatures(ComponentName who, int userHandle) {
   2691         if (!mHasFeature) {
   2692             return 0;
   2693         }
   2694         enforceCrossUserPermission(userHandle);
   2695         synchronized (this) {
   2696             if (who != null) {
   2697                 ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
   2698                 return (admin != null) ? admin.disabledKeyguardFeatures : 0;
   2699             }
   2700 
   2701             // Determine which keyguard features are disabled for any active admins.
   2702             DevicePolicyData policy = getUserData(userHandle);
   2703             final int N = policy.mAdminList.size();
   2704             int which = 0;
   2705             for (int i = 0; i < N; i++) {
   2706                 ActiveAdmin admin = policy.mAdminList.get(i);
   2707                 which |= admin.disabledKeyguardFeatures;
   2708             }
   2709             return which;
   2710         }
   2711     }
   2712 
   2713     @Override
   2714     public boolean setDeviceOwner(String packageName, String ownerName) {
   2715         if (!mHasFeature) {
   2716             return false;
   2717         }
   2718         if (packageName == null
   2719                 || !DeviceOwner.isInstalled(packageName, mContext.getPackageManager())) {
   2720             throw new IllegalArgumentException("Invalid package name " + packageName
   2721                     + " for device owner");
   2722         }
   2723         synchronized (this) {
   2724             if (mDeviceOwner == null && !isDeviceProvisioned()) {
   2725                 mDeviceOwner = new DeviceOwner(packageName, ownerName);
   2726                 mDeviceOwner.writeOwnerFile();
   2727                 return true;
   2728             } else {
   2729                 throw new IllegalStateException("Trying to set device owner to " + packageName
   2730                         + ", owner=" + mDeviceOwner.getPackageName()
   2731                         + ", device_provisioned=" + isDeviceProvisioned());
   2732             }
   2733         }
   2734     }
   2735 
   2736     @Override
   2737     public boolean isDeviceOwner(String packageName) {
   2738         if (!mHasFeature) {
   2739             return false;
   2740         }
   2741         synchronized (this) {
   2742             return mDeviceOwner != null
   2743                     && mDeviceOwner.getPackageName().equals(packageName);
   2744         }
   2745     }
   2746 
   2747     @Override
   2748     public String getDeviceOwner() {
   2749         if (!mHasFeature) {
   2750             return null;
   2751         }
   2752         synchronized (this) {
   2753             if (mDeviceOwner != null) {
   2754                 return mDeviceOwner.getPackageName();
   2755             }
   2756         }
   2757         return null;
   2758     }
   2759 
   2760     @Override
   2761     public String getDeviceOwnerName() {
   2762         if (!mHasFeature) {
   2763             return null;
   2764         }
   2765         mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
   2766         synchronized (this) {
   2767             if (mDeviceOwner != null) {
   2768                 return mDeviceOwner.getName();
   2769             }
   2770         }
   2771         return null;
   2772     }
   2773 
   2774     private boolean isDeviceProvisioned() {
   2775         return Settings.Global.getInt(mContext.getContentResolver(),
   2776                 Settings.Global.DEVICE_PROVISIONED, 0) > 0;
   2777     }
   2778 
   2779     private void enforceCrossUserPermission(int userHandle) {
   2780         if (userHandle < 0) {
   2781             throw new IllegalArgumentException("Invalid userId " + userHandle);
   2782         }
   2783         final int callingUid = Binder.getCallingUid();
   2784         if (userHandle == UserHandle.getUserId(callingUid)) return;
   2785         if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
   2786             mContext.enforceCallingOrSelfPermission(
   2787                     android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, "Must be system or have"
   2788                     + " INTERACT_ACROSS_USERS_FULL permission");
   2789         }
   2790     }
   2791 
   2792     private void enableIfNecessary(String packageName, int userId) {
   2793         try {
   2794             IPackageManager ipm = AppGlobals.getPackageManager();
   2795             ApplicationInfo ai = ipm.getApplicationInfo(packageName,
   2796                     PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
   2797                     userId);
   2798             if (ai.enabledSetting
   2799                     == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
   2800                 ipm.setApplicationEnabledSetting(packageName,
   2801                         PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
   2802                         PackageManager.DONT_KILL_APP, userId, "DevicePolicyManager");
   2803             }
   2804         } catch (RemoteException e) {
   2805         }
   2806     }
   2807 
   2808     @Override
   2809     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
   2810         if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
   2811                 != PackageManager.PERMISSION_GRANTED) {
   2812 
   2813             pw.println("Permission Denial: can't dump DevicePolicyManagerService from from pid="
   2814                     + Binder.getCallingPid()
   2815                     + ", uid=" + Binder.getCallingUid());
   2816             return;
   2817         }
   2818 
   2819         final Printer p = new PrintWriterPrinter(pw);
   2820 
   2821         synchronized (this) {
   2822             p.println("Current Device Policy Manager state:");
   2823 
   2824             int userCount = mUserData.size();
   2825             for (int u = 0; u < userCount; u++) {
   2826                 DevicePolicyData policy = getUserData(mUserData.keyAt(u));
   2827                 p.println("  Enabled Device Admins (User " + policy.mUserHandle + "):");
   2828                 final int N = policy.mAdminList.size();
   2829                 for (int i=0; i<N; i++) {
   2830                     ActiveAdmin ap = policy.mAdminList.get(i);
   2831                     if (ap != null) {
   2832                         pw.print("  "); pw.print(ap.info.getComponent().flattenToShortString());
   2833                                 pw.println(":");
   2834                         ap.dump("    ", pw);
   2835                     }
   2836                 }
   2837 
   2838                 pw.println(" ");
   2839                 pw.print("  mPasswordOwner="); pw.println(policy.mPasswordOwner);
   2840             }
   2841         }
   2842     }
   2843 
   2844     static class DeviceOwner {
   2845         private static final String DEVICE_OWNER_XML = "device_owner.xml";
   2846         private static final String TAG_DEVICE_OWNER = "device-owner";
   2847         private static final String ATTR_NAME = "name";
   2848         private static final String ATTR_PACKAGE = "package";
   2849         private String mPackageName;
   2850         private String mOwnerName;
   2851 
   2852         DeviceOwner() {
   2853             readOwnerFile();
   2854         }
   2855 
   2856         DeviceOwner(String packageName, String ownerName) {
   2857             this.mPackageName = packageName;
   2858             this.mOwnerName = ownerName;
   2859         }
   2860 
   2861         static boolean isRegistered() {
   2862             return new File(Environment.getSystemSecureDirectory(),
   2863                     DEVICE_OWNER_XML).exists();
   2864         }
   2865 
   2866         String getPackageName() {
   2867             return mPackageName;
   2868         }
   2869 
   2870         String getName() {
   2871             return mOwnerName;
   2872         }
   2873 
   2874         static boolean isInstalled(String packageName, PackageManager pm) {
   2875             try {
   2876                 PackageInfo pi;
   2877                 if ((pi = pm.getPackageInfo(packageName, 0)) != null) {
   2878                     if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
   2879                         return true;
   2880                     }
   2881                 }
   2882             } catch (NameNotFoundException nnfe) {
   2883                 Slog.w(TAG, "Device Owner package " + packageName + " not installed.");
   2884             }
   2885             return false;
   2886         }
   2887 
   2888         void readOwnerFile() {
   2889             AtomicFile file = new AtomicFile(new File(Environment.getSystemSecureDirectory(),
   2890                     DEVICE_OWNER_XML));
   2891             try {
   2892                 FileInputStream input = file.openRead();
   2893                 XmlPullParser parser = Xml.newPullParser();
   2894                 parser.setInput(input, null);
   2895                 int type;
   2896                 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT
   2897                         && type != XmlPullParser.START_TAG) {
   2898                 }
   2899                 String tag = parser.getName();
   2900                 if (!TAG_DEVICE_OWNER.equals(tag)) {
   2901                     throw new XmlPullParserException(
   2902                             "Device Owner file does not start with device-owner tag: found " + tag);
   2903                 }
   2904                 mPackageName = parser.getAttributeValue(null, ATTR_PACKAGE);
   2905                 mOwnerName = parser.getAttributeValue(null, ATTR_NAME);
   2906                 input.close();
   2907             } catch (XmlPullParserException xppe) {
   2908                 Slog.e(TAG, "Error parsing device-owner file\n" + xppe);
   2909             } catch (IOException ioe) {
   2910                 Slog.e(TAG, "IO Exception when reading device-owner file\n" + ioe);
   2911             }
   2912         }
   2913 
   2914         void writeOwnerFile() {
   2915             synchronized (this) {
   2916                 writeOwnerFileLocked();
   2917             }
   2918         }
   2919 
   2920         private void writeOwnerFileLocked() {
   2921             AtomicFile file = new AtomicFile(new File(Environment.getSystemSecureDirectory(),
   2922                     DEVICE_OWNER_XML));
   2923             try {
   2924                 FileOutputStream output = file.startWrite();
   2925                 XmlSerializer out = new FastXmlSerializer();
   2926                 out.setOutput(output, "utf-8");
   2927                 out.startDocument(null, true);
   2928                 out.startTag(null, TAG_DEVICE_OWNER);
   2929                 out.attribute(null, ATTR_PACKAGE, mPackageName);
   2930                 if (mOwnerName != null) {
   2931                     out.attribute(null, ATTR_NAME, mOwnerName);
   2932                 }
   2933                 out.endTag(null, TAG_DEVICE_OWNER);
   2934                 out.endDocument();
   2935                 out.flush();
   2936                 file.finishWrite(output);
   2937             } catch (IOException ioe) {
   2938                 Slog.e(TAG, "IO Exception when writing device-owner file\n" + ioe);
   2939             }
   2940         }
   2941     }
   2942 }
   2943