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