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