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