DevicePolicyManagerService.java revision 1e958398232cb11935f5341d71df52c5455c620f
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 != null) {
1218            if (mDeviceOwner.hasDeviceOwner()) {
1219                try {
1220                    mAppOpsService.setDeviceOwner(mDeviceOwner.getDeviceOwnerPackageName());
1221                } catch (RemoteException e) {
1222                    Log.w(LOG_TAG, "Unable to notify AppOpsService of DeviceOwner", e);
1223                }
1224            }
1225            for (Integer i : mDeviceOwner.getProfileOwnerKeys()) {
1226                try {
1227                    mAppOpsService.setProfileOwner(mDeviceOwner.getProfileOwnerPackageName(i), i);
1228                } catch (RemoteException e) {
1229                    Log.w(LOG_TAG, "Unable to notify AppOpsService of ProfileOwner", e);
1230                }
1231            }
1232        }
1233    }
1234
1235    private void handlePasswordExpirationNotification(int userHandle) {
1236        synchronized (this) {
1237            final long now = System.currentTimeMillis();
1238
1239            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1240            for (UserInfo ui : profiles) {
1241                int profileUserHandle = ui.getUserHandle().getIdentifier();
1242                final DevicePolicyData policy = getUserData(profileUserHandle);
1243                final int count = policy.mAdminList.size();
1244                if (count > 0) {
1245                    for (int i = 0; i < count; i++) {
1246                        final ActiveAdmin admin = policy.mAdminList.get(i);
1247                        if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)
1248                                && admin.passwordExpirationTimeout > 0L
1249                                && now >= admin.passwordExpirationDate - EXPIRATION_GRACE_PERIOD_MS
1250                                && admin.passwordExpirationDate > 0L) {
1251                            sendAdminCommandLocked(admin,
1252                                    DeviceAdminReceiver.ACTION_PASSWORD_EXPIRING);
1253                        }
1254                    }
1255                }
1256            }
1257            setExpirationAlarmCheckLocked(mContext, getUserData(userHandle));
1258        }
1259    }
1260
1261    private void manageMonitoringCertificateNotification(Intent intent) {
1262        final NotificationManager notificationManager = getNotificationManager();
1263
1264        final boolean hasCert = DevicePolicyManager.hasAnyCaCertsInstalled();
1265        if (! hasCert) {
1266            if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
1267                for (UserInfo user : mUserManager.getUsers()) {
1268                    notificationManager.cancelAsUser(
1269                            null, MONITORING_CERT_NOTIFICATION_ID, user.getUserHandle());
1270                }
1271            }
1272            return;
1273        }
1274        final boolean isManaged = getDeviceOwner() != null;
1275        int smallIconId;
1276        String contentText;
1277        if (isManaged) {
1278            contentText = mContext.getString(R.string.ssl_ca_cert_noti_managed,
1279                    getDeviceOwnerName());
1280            smallIconId = R.drawable.stat_sys_certificate_info;
1281        } else {
1282            contentText = mContext.getString(R.string.ssl_ca_cert_noti_by_unknown);
1283            smallIconId = android.R.drawable.stat_sys_warning;
1284        }
1285
1286        Intent dialogIntent = new Intent(Settings.ACTION_MONITORING_CERT_INFO);
1287        dialogIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
1288        dialogIntent.setPackage("com.android.settings");
1289        // Notification will be sent individually to all users. The activity should start as
1290        // whichever user is current when it starts.
1291        PendingIntent notifyIntent = PendingIntent.getActivityAsUser(mContext, 0, dialogIntent,
1292                PendingIntent.FLAG_UPDATE_CURRENT, null, UserHandle.CURRENT);
1293
1294        Notification noti = new Notification.Builder(mContext)
1295            .setSmallIcon(smallIconId)
1296            .setContentTitle(mContext.getString(R.string.ssl_ca_cert_warning))
1297            .setContentText(contentText)
1298            .setContentIntent(notifyIntent)
1299            .setPriority(Notification.PRIORITY_HIGH)
1300            .setShowWhen(false)
1301            .build();
1302
1303        // If this is a boot intent, this will fire for each user. But if this is a storage changed
1304        // intent, it will fire once, so we need to notify all users.
1305        if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
1306            for (UserInfo user : mUserManager.getUsers()) {
1307                notificationManager.notifyAsUser(
1308                        null, MONITORING_CERT_NOTIFICATION_ID, noti, user.getUserHandle());
1309            }
1310        } else {
1311            notificationManager.notifyAsUser(
1312                    null, MONITORING_CERT_NOTIFICATION_ID, noti, UserHandle.CURRENT);
1313        }
1314    }
1315
1316    /**
1317     * @param adminReceiver The admin to add
1318     * @param refreshing true = update an active admin, no error
1319     */
1320    public void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle) {
1321        if (!mHasFeature) {
1322            return;
1323        }
1324        mContext.enforceCallingOrSelfPermission(
1325                android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
1326        enforceCrossUserPermission(userHandle);
1327
1328        DevicePolicyData policy = getUserData(userHandle);
1329        DeviceAdminInfo info = findAdmin(adminReceiver, userHandle);
1330        if (info == null) {
1331            throw new IllegalArgumentException("Bad admin: " + adminReceiver);
1332        }
1333        synchronized (this) {
1334            long ident = Binder.clearCallingIdentity();
1335            try {
1336                if (!refreshing
1337                        && getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null) {
1338                    throw new IllegalArgumentException("Admin is already added");
1339                }
1340                ActiveAdmin newAdmin = new ActiveAdmin(info);
1341                policy.mAdminMap.put(adminReceiver, newAdmin);
1342                int replaceIndex = -1;
1343                if (refreshing) {
1344                    final int N = policy.mAdminList.size();
1345                    for (int i=0; i < N; i++) {
1346                        ActiveAdmin oldAdmin = policy.mAdminList.get(i);
1347                        if (oldAdmin.info.getComponent().equals(adminReceiver)) {
1348                            replaceIndex = i;
1349                            break;
1350                        }
1351                    }
1352                }
1353                if (replaceIndex == -1) {
1354                    policy.mAdminList.add(newAdmin);
1355                    enableIfNecessary(info.getPackageName(), userHandle);
1356                } else {
1357                    policy.mAdminList.set(replaceIndex, newAdmin);
1358                }
1359                saveSettingsLocked(userHandle);
1360                sendAdminCommandLocked(newAdmin, DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED);
1361            } finally {
1362                Binder.restoreCallingIdentity(ident);
1363            }
1364        }
1365    }
1366
1367    public boolean isAdminActive(ComponentName adminReceiver, int userHandle) {
1368        if (!mHasFeature) {
1369            return false;
1370        }
1371        enforceCrossUserPermission(userHandle);
1372        synchronized (this) {
1373            return getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null;
1374        }
1375    }
1376
1377    public boolean hasGrantedPolicy(ComponentName adminReceiver, int policyId, int userHandle) {
1378        if (!mHasFeature) {
1379            return false;
1380        }
1381        enforceCrossUserPermission(userHandle);
1382        synchronized (this) {
1383            ActiveAdmin administrator = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
1384            if (administrator == null) {
1385                throw new SecurityException("No active admin " + adminReceiver);
1386            }
1387            return administrator.info.usesPolicy(policyId);
1388        }
1389    }
1390
1391    @SuppressWarnings("unchecked")
1392    public List<ComponentName> getActiveAdmins(int userHandle) {
1393        if (!mHasFeature) {
1394            return Collections.EMPTY_LIST;
1395        }
1396
1397        enforceCrossUserPermission(userHandle);
1398        synchronized (this) {
1399            DevicePolicyData policy = getUserData(userHandle);
1400            final int N = policy.mAdminList.size();
1401            if (N <= 0) {
1402                return null;
1403            }
1404            ArrayList<ComponentName> res = new ArrayList<ComponentName>(N);
1405            for (int i=0; i<N; i++) {
1406                res.add(policy.mAdminList.get(i).info.getComponent());
1407            }
1408            return res;
1409        }
1410    }
1411
1412    public boolean packageHasActiveAdmins(String packageName, int userHandle) {
1413        if (!mHasFeature) {
1414            return false;
1415        }
1416        enforceCrossUserPermission(userHandle);
1417        synchronized (this) {
1418            DevicePolicyData policy = getUserData(userHandle);
1419            final int N = policy.mAdminList.size();
1420            for (int i=0; i<N; i++) {
1421                if (policy.mAdminList.get(i).info.getPackageName().equals(packageName)) {
1422                    return true;
1423                }
1424            }
1425            return false;
1426        }
1427    }
1428
1429    public void removeActiveAdmin(ComponentName adminReceiver, int userHandle) {
1430        if (!mHasFeature) {
1431            return;
1432        }
1433        enforceCrossUserPermission(userHandle);
1434        synchronized (this) {
1435            ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle);
1436            if (admin == null) {
1437                return;
1438            }
1439            if (admin.getUid() != Binder.getCallingUid()) {
1440                // If trying to remove device owner, refuse when the caller is not the owner.
1441                if (isDeviceOwner(adminReceiver.getPackageName())) {
1442                    return;
1443                }
1444                mContext.enforceCallingOrSelfPermission(
1445                        android.Manifest.permission.MANAGE_DEVICE_ADMINS, null);
1446            }
1447            long ident = Binder.clearCallingIdentity();
1448            try {
1449                removeActiveAdminLocked(adminReceiver, userHandle);
1450            } finally {
1451                Binder.restoreCallingIdentity(ident);
1452            }
1453        }
1454    }
1455
1456    public void setPasswordQuality(ComponentName who, int quality, int userHandle) {
1457        if (!mHasFeature) {
1458            return;
1459        }
1460        validateQualityConstant(quality);
1461        enforceCrossUserPermission(userHandle);
1462
1463        synchronized (this) {
1464            if (who == null) {
1465                throw new NullPointerException("ComponentName is null");
1466            }
1467            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1468                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1469            if (ap.passwordQuality != quality) {
1470                ap.passwordQuality = quality;
1471                saveSettingsLocked(userHandle);
1472            }
1473        }
1474    }
1475
1476    public int getPasswordQuality(ComponentName who, int userHandle) {
1477        if (!mHasFeature) {
1478            return DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
1479        }
1480        enforceCrossUserPermission(userHandle);
1481        synchronized (this) {
1482            int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
1483
1484            if (who != null) {
1485                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1486                return admin != null ? admin.passwordQuality : mode;
1487            }
1488
1489            // Return strictest policy for this user and profiles that are visible from this user.
1490            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1491            for (UserInfo userInfo : profiles) {
1492                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
1493                final int N = policy.mAdminList.size();
1494                for (int i=0; i<N; i++) {
1495                    ActiveAdmin admin = policy.mAdminList.get(i);
1496                    if (mode < admin.passwordQuality) {
1497                        mode = admin.passwordQuality;
1498                    }
1499                }
1500            }
1501            return mode;
1502        }
1503    }
1504
1505    public void setPasswordMinimumLength(ComponentName who, int length, int userHandle) {
1506        if (!mHasFeature) {
1507            return;
1508        }
1509        enforceCrossUserPermission(userHandle);
1510        synchronized (this) {
1511            if (who == null) {
1512                throw new NullPointerException("ComponentName is null");
1513            }
1514            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1515                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1516            if (ap.minimumPasswordLength != length) {
1517                ap.minimumPasswordLength = length;
1518                saveSettingsLocked(userHandle);
1519            }
1520        }
1521    }
1522
1523    public int getPasswordMinimumLength(ComponentName who, int userHandle) {
1524        if (!mHasFeature) {
1525            return 0;
1526        }
1527        enforceCrossUserPermission(userHandle);
1528        synchronized (this) {
1529            int length = 0;
1530
1531            if (who != null) {
1532                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1533                return admin != null ? admin.minimumPasswordLength : length;
1534            }
1535
1536            // Return strictest policy for this user and profiles that are visible from this user.
1537            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1538            for (UserInfo userInfo : profiles) {
1539                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
1540                final int N = policy.mAdminList.size();
1541                for (int i=0; i<N; i++) {
1542                    ActiveAdmin admin = policy.mAdminList.get(i);
1543                    if (length < admin.minimumPasswordLength) {
1544                        length = admin.minimumPasswordLength;
1545                    }
1546                }
1547            }
1548            return length;
1549        }
1550    }
1551
1552    public void setPasswordHistoryLength(ComponentName who, int length, int userHandle) {
1553        if (!mHasFeature) {
1554            return;
1555        }
1556        enforceCrossUserPermission(userHandle);
1557        synchronized (this) {
1558            if (who == null) {
1559                throw new NullPointerException("ComponentName is null");
1560            }
1561            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1562                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1563            if (ap.passwordHistoryLength != length) {
1564                ap.passwordHistoryLength = length;
1565                saveSettingsLocked(userHandle);
1566            }
1567        }
1568    }
1569
1570    public int getPasswordHistoryLength(ComponentName who, int userHandle) {
1571        if (!mHasFeature) {
1572            return 0;
1573        }
1574        enforceCrossUserPermission(userHandle);
1575        synchronized (this) {
1576            int length = 0;
1577
1578            if (who != null) {
1579                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1580                return admin != null ? admin.passwordHistoryLength : length;
1581            }
1582
1583            // Return strictest policy for this user and profiles that are visible from this user.
1584            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1585            for (UserInfo userInfo : profiles) {
1586                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
1587                final int N = policy.mAdminList.size();
1588                for (int i = 0; i < N; i++) {
1589                    ActiveAdmin admin = policy.mAdminList.get(i);
1590                    if (length < admin.passwordHistoryLength) {
1591                        length = admin.passwordHistoryLength;
1592                    }
1593                }
1594            }
1595            return length;
1596        }
1597    }
1598
1599    public void setPasswordExpirationTimeout(ComponentName who, long timeout, int userHandle) {
1600        if (!mHasFeature) {
1601            return;
1602        }
1603        enforceCrossUserPermission(userHandle);
1604        synchronized (this) {
1605            if (who == null) {
1606                throw new NullPointerException("ComponentName is null");
1607            }
1608            if (timeout < 0) {
1609                throw new IllegalArgumentException("Timeout must be >= 0 ms");
1610            }
1611            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1612                    DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD);
1613            // Calling this API automatically bumps the expiration date
1614            final long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
1615            ap.passwordExpirationDate = expiration;
1616            ap.passwordExpirationTimeout = timeout;
1617            if (timeout > 0L) {
1618                Slog.w(LOG_TAG, "setPasswordExpiration(): password will expire on "
1619                        + DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT)
1620                        .format(new Date(expiration)));
1621            }
1622            saveSettingsLocked(userHandle);
1623            // in case this is the first one
1624            setExpirationAlarmCheckLocked(mContext, getUserData(userHandle));
1625        }
1626    }
1627
1628    /**
1629     * Return a single admin's expiration cycle time, or the min of all cycle times.
1630     * Returns 0 if not configured.
1631     */
1632    public long getPasswordExpirationTimeout(ComponentName who, int userHandle) {
1633        if (!mHasFeature) {
1634            return 0L;
1635        }
1636        enforceCrossUserPermission(userHandle);
1637        synchronized (this) {
1638            long timeout = 0L;
1639
1640            if (who != null) {
1641                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1642                return admin != null ? admin.passwordExpirationTimeout : timeout;
1643            }
1644
1645            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1646            for (UserInfo userInfo : profiles) {
1647                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
1648                final int N = policy.mAdminList.size();
1649                for (int i = 0; i < N; i++) {
1650                    ActiveAdmin admin = policy.mAdminList.get(i);
1651                    if (timeout == 0L || (admin.passwordExpirationTimeout != 0L
1652                            && timeout > admin.passwordExpirationTimeout)) {
1653                        timeout = admin.passwordExpirationTimeout;
1654                    }
1655                }
1656            }
1657            return timeout;
1658        }
1659    }
1660
1661    /**
1662     * Return a single admin's expiration date/time, or the min (soonest) for all admins.
1663     * Returns 0 if not configured.
1664     */
1665    private long getPasswordExpirationLocked(ComponentName who, int userHandle) {
1666        long timeout = 0L;
1667
1668        if (who != null) {
1669            ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1670            return admin != null ? admin.passwordExpirationDate : timeout;
1671        }
1672
1673        List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1674        for (UserInfo userInfo : profiles) {
1675            DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
1676            final int N = policy.mAdminList.size();
1677            for (int i = 0; i < N; i++) {
1678                ActiveAdmin admin = policy.mAdminList.get(i);
1679                if (timeout == 0L || (admin.passwordExpirationDate != 0
1680                        && timeout > admin.passwordExpirationDate)) {
1681                    timeout = admin.passwordExpirationDate;
1682                }
1683            }
1684        }
1685        return timeout;
1686    }
1687
1688    public long getPasswordExpiration(ComponentName who, int userHandle) {
1689        if (!mHasFeature) {
1690            return 0L;
1691        }
1692        enforceCrossUserPermission(userHandle);
1693        synchronized (this) {
1694            return getPasswordExpirationLocked(who, userHandle);
1695        }
1696    }
1697
1698    public void setPasswordMinimumUpperCase(ComponentName who, int length, int userHandle) {
1699        if (!mHasFeature) {
1700            return;
1701        }
1702        enforceCrossUserPermission(userHandle);
1703        synchronized (this) {
1704            if (who == null) {
1705                throw new NullPointerException("ComponentName is null");
1706            }
1707            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1708                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1709            if (ap.minimumPasswordUpperCase != length) {
1710                ap.minimumPasswordUpperCase = length;
1711                saveSettingsLocked(userHandle);
1712            }
1713        }
1714    }
1715
1716    public int getPasswordMinimumUpperCase(ComponentName who, int userHandle) {
1717        if (!mHasFeature) {
1718            return 0;
1719        }
1720        enforceCrossUserPermission(userHandle);
1721        synchronized (this) {
1722            int length = 0;
1723
1724            if (who != null) {
1725                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1726                return admin != null ? admin.minimumPasswordUpperCase : length;
1727            }
1728
1729            // Return strictest policy for this user and profiles that are visible from this user.
1730            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1731            for (UserInfo userInfo : profiles) {
1732                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
1733                final int N = policy.mAdminList.size();
1734                for (int i=0; i<N; i++) {
1735                    ActiveAdmin admin = policy.mAdminList.get(i);
1736                    if (length < admin.minimumPasswordUpperCase) {
1737                        length = admin.minimumPasswordUpperCase;
1738                    }
1739                }
1740            }
1741            return length;
1742        }
1743    }
1744
1745    public void setPasswordMinimumLowerCase(ComponentName who, int length, int userHandle) {
1746        enforceCrossUserPermission(userHandle);
1747        synchronized (this) {
1748            if (who == null) {
1749                throw new NullPointerException("ComponentName is null");
1750            }
1751            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1752                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1753            if (ap.minimumPasswordLowerCase != length) {
1754                ap.minimumPasswordLowerCase = length;
1755                saveSettingsLocked(userHandle);
1756            }
1757        }
1758    }
1759
1760    public int getPasswordMinimumLowerCase(ComponentName who, int userHandle) {
1761        if (!mHasFeature) {
1762            return 0;
1763        }
1764        enforceCrossUserPermission(userHandle);
1765        synchronized (this) {
1766            int length = 0;
1767
1768            if (who != null) {
1769                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1770                return admin != null ? admin.minimumPasswordLowerCase : length;
1771            }
1772
1773            // Return strictest policy for this user and profiles that are visible from this user.
1774            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1775            for (UserInfo userInfo : profiles) {
1776                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
1777                final int N = policy.mAdminList.size();
1778                for (int i=0; i<N; i++) {
1779                    ActiveAdmin admin = policy.mAdminList.get(i);
1780                    if (length < admin.minimumPasswordLowerCase) {
1781                        length = admin.minimumPasswordLowerCase;
1782                    }
1783                }
1784            }
1785            return length;
1786        }
1787    }
1788
1789    public void setPasswordMinimumLetters(ComponentName who, int length, int userHandle) {
1790        if (!mHasFeature) {
1791            return;
1792        }
1793        enforceCrossUserPermission(userHandle);
1794        synchronized (this) {
1795            if (who == null) {
1796                throw new NullPointerException("ComponentName is null");
1797            }
1798            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1799                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1800            if (ap.minimumPasswordLetters != length) {
1801                ap.minimumPasswordLetters = length;
1802                saveSettingsLocked(userHandle);
1803            }
1804        }
1805    }
1806
1807    public int getPasswordMinimumLetters(ComponentName who, int userHandle) {
1808        if (!mHasFeature) {
1809            return 0;
1810        }
1811        enforceCrossUserPermission(userHandle);
1812        synchronized (this) {
1813            int length = 0;
1814
1815            if (who != null) {
1816                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1817                return admin != null ? admin.minimumPasswordLetters : length;
1818            }
1819
1820            // Return strictest policy for this user and profiles that are visible from this user.
1821            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1822            for (UserInfo userInfo : profiles) {
1823                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
1824                final int N = policy.mAdminList.size();
1825                for (int i=0; i<N; i++) {
1826                    ActiveAdmin admin = policy.mAdminList.get(i);
1827                    if (length < admin.minimumPasswordLetters) {
1828                        length = admin.minimumPasswordLetters;
1829                    }
1830                }
1831            }
1832            return length;
1833        }
1834    }
1835
1836    public void setPasswordMinimumNumeric(ComponentName who, int length, int userHandle) {
1837        if (!mHasFeature) {
1838            return;
1839        }
1840        enforceCrossUserPermission(userHandle);
1841        synchronized (this) {
1842            if (who == null) {
1843                throw new NullPointerException("ComponentName is null");
1844            }
1845            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1846                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1847            if (ap.minimumPasswordNumeric != length) {
1848                ap.minimumPasswordNumeric = length;
1849                saveSettingsLocked(userHandle);
1850            }
1851        }
1852    }
1853
1854    public int getPasswordMinimumNumeric(ComponentName who, int userHandle) {
1855        if (!mHasFeature) {
1856            return 0;
1857        }
1858        enforceCrossUserPermission(userHandle);
1859        synchronized (this) {
1860            int length = 0;
1861
1862            if (who != null) {
1863                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1864                return admin != null ? admin.minimumPasswordNumeric : length;
1865            }
1866
1867            // Return strictest policy for this user and profiles that are visible from this user.
1868            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1869            for (UserInfo userInfo : profiles) {
1870                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
1871                final int N = policy.mAdminList.size();
1872                for (int i = 0; i < N; i++) {
1873                    ActiveAdmin admin = policy.mAdminList.get(i);
1874                    if (length < admin.minimumPasswordNumeric) {
1875                        length = admin.minimumPasswordNumeric;
1876                    }
1877                }
1878            }
1879            return length;
1880        }
1881    }
1882
1883    public void setPasswordMinimumSymbols(ComponentName who, int length, int userHandle) {
1884        if (!mHasFeature) {
1885            return;
1886        }
1887        enforceCrossUserPermission(userHandle);
1888        synchronized (this) {
1889            if (who == null) {
1890                throw new NullPointerException("ComponentName is null");
1891            }
1892            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1893                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1894            if (ap.minimumPasswordSymbols != length) {
1895                ap.minimumPasswordSymbols = length;
1896                saveSettingsLocked(userHandle);
1897            }
1898        }
1899    }
1900
1901    public int getPasswordMinimumSymbols(ComponentName who, int userHandle) {
1902        if (!mHasFeature) {
1903            return 0;
1904        }
1905        enforceCrossUserPermission(userHandle);
1906        synchronized (this) {
1907            int length = 0;
1908
1909            if (who != null) {
1910                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1911                return admin != null ? admin.minimumPasswordSymbols : length;
1912            }
1913
1914            // Return strictest policy for this user and profiles that are visible from this user.
1915            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1916            for (UserInfo userInfo : profiles) {
1917                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
1918                final int N = policy.mAdminList.size();
1919                for (int i=0; i<N; i++) {
1920                    ActiveAdmin admin = policy.mAdminList.get(i);
1921                    if (length < admin.minimumPasswordSymbols) {
1922                        length = admin.minimumPasswordSymbols;
1923                    }
1924                }
1925            }
1926            return length;
1927        }
1928    }
1929
1930    public void setPasswordMinimumNonLetter(ComponentName who, int length, int userHandle) {
1931        if (!mHasFeature) {
1932            return;
1933        }
1934        enforceCrossUserPermission(userHandle);
1935        synchronized (this) {
1936            if (who == null) {
1937                throw new NullPointerException("ComponentName is null");
1938            }
1939            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
1940                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1941            if (ap.minimumPasswordNonLetter != length) {
1942                ap.minimumPasswordNonLetter = length;
1943                saveSettingsLocked(userHandle);
1944            }
1945        }
1946    }
1947
1948    public int getPasswordMinimumNonLetter(ComponentName who, int userHandle) {
1949        if (!mHasFeature) {
1950            return 0;
1951        }
1952        enforceCrossUserPermission(userHandle);
1953        synchronized (this) {
1954            int length = 0;
1955
1956            if (who != null) {
1957                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
1958                return admin != null ? admin.minimumPasswordNonLetter : length;
1959            }
1960
1961            // Return strictest policy for this user and profiles that are visible from this user.
1962            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
1963            for (UserInfo userInfo : profiles) {
1964                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
1965                final int N = policy.mAdminList.size();
1966                for (int i=0; i<N; i++) {
1967                    ActiveAdmin admin = policy.mAdminList.get(i);
1968                    if (length < admin.minimumPasswordNonLetter) {
1969                        length = admin.minimumPasswordNonLetter;
1970                    }
1971                }
1972            }
1973            return length;
1974        }
1975    }
1976
1977    public boolean isActivePasswordSufficient(int userHandle) {
1978        if (!mHasFeature) {
1979            return true;
1980        }
1981        enforceCrossUserPermission(userHandle);
1982
1983        synchronized (this) {
1984
1985            // The active password is stored in the user that runs the launcher
1986            // If the user this is called from is part of a profile group, that is the parent
1987            // of the group.
1988            UserInfo parent = getProfileParent(userHandle);
1989            int id = parent == null ? userHandle : parent.id;
1990            DevicePolicyData policy = getUserData(id);
1991
1992            // This API can only be called by an active device admin,
1993            // so try to retrieve it to check that the caller is one.
1994            getActiveAdminForCallerLocked(null,
1995                    DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD);
1996            if (policy.mActivePasswordQuality < getPasswordQuality(null, userHandle)
1997                    || policy.mActivePasswordLength < getPasswordMinimumLength(null, userHandle)) {
1998                return false;
1999            }
2000            if (policy.mActivePasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
2001                return true;
2002            }
2003            return policy.mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null, userHandle)
2004                && policy.mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null, userHandle)
2005                && policy.mActivePasswordLetters >= getPasswordMinimumLetters(null, userHandle)
2006                && policy.mActivePasswordNumeric >= getPasswordMinimumNumeric(null, userHandle)
2007                && policy.mActivePasswordSymbols >= getPasswordMinimumSymbols(null, userHandle)
2008                && policy.mActivePasswordNonLetter >= getPasswordMinimumNonLetter(null, userHandle);
2009        }
2010    }
2011
2012    public int getCurrentFailedPasswordAttempts(int userHandle) {
2013        synchronized (this) {
2014            // This API can only be called by an active device admin,
2015            // so try to retrieve it to check that the caller is one.
2016            getActiveAdminForCallerLocked(null,
2017                    DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
2018
2019            // The active password is stored in the parent.
2020            DevicePolicyData policy = getUserData(getProfileParent(userHandle).id);
2021
2022            return policy.mFailedPasswordAttempts;
2023        }
2024    }
2025
2026    public void setMaximumFailedPasswordsForWipe(ComponentName who, int num, int userHandle) {
2027        if (!mHasFeature) {
2028            return;
2029        }
2030        enforceCrossUserPermission(userHandle);
2031        synchronized (this) {
2032            if (who == null) {
2033                throw new NullPointerException("ComponentName is null");
2034            }
2035            // This API can only be called by an active device admin,
2036            // so try to retrieve it to check that the caller is one.
2037            getActiveAdminForCallerLocked(who,
2038                    DeviceAdminInfo.USES_POLICY_WIPE_DATA);
2039            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
2040                    DeviceAdminInfo.USES_POLICY_WATCH_LOGIN);
2041            if (ap.maximumFailedPasswordsForWipe != num) {
2042                ap.maximumFailedPasswordsForWipe = num;
2043                saveSettingsLocked(userHandle);
2044            }
2045        }
2046    }
2047
2048    public int getMaximumFailedPasswordsForWipe(ComponentName who, int userHandle) {
2049        if (!mHasFeature) {
2050            return 0;
2051        }
2052        enforceCrossUserPermission(userHandle);
2053        synchronized (this) {
2054            int count = 0;
2055
2056            if (who != null) {
2057                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
2058                return admin != null ? admin.maximumFailedPasswordsForWipe : count;
2059            }
2060
2061            // Return strictest policy for this user and profiles that are visible from this user.
2062            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
2063            for (UserInfo userInfo : profiles) {
2064                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
2065                final int N = policy.mAdminList.size();
2066                for (int i=0; i<N; i++) {
2067                    ActiveAdmin admin = policy.mAdminList.get(i);
2068                    if (count == 0) {
2069                        count = admin.maximumFailedPasswordsForWipe;
2070                    } else if (admin.maximumFailedPasswordsForWipe != 0
2071                            && count > admin.maximumFailedPasswordsForWipe) {
2072                        count = admin.maximumFailedPasswordsForWipe;
2073                    }
2074                }
2075            }
2076            return count;
2077        }
2078    }
2079
2080    public boolean resetPassword(String password, int flags, int userHandle) {
2081        if (!mHasFeature) {
2082            return false;
2083        }
2084        enforceCrossUserPermission(userHandle);
2085        enforceNotManagedProfile(userHandle, "reset the password");
2086
2087        int quality;
2088        synchronized (this) {
2089            // This api can only be called by an active device admin,
2090            // so try to retrieve it to check that the caller is one.
2091            getActiveAdminForCallerLocked(null,
2092                    DeviceAdminInfo.USES_POLICY_RESET_PASSWORD);
2093            quality = getPasswordQuality(null, userHandle);
2094            if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
2095                int realQuality = LockPatternUtils.computePasswordQuality(password);
2096                if (realQuality < quality
2097                        && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
2098                    Slog.w(LOG_TAG, "resetPassword: password quality 0x"
2099                            + Integer.toHexString(realQuality)
2100                            + " does not meet required quality 0x"
2101                            + Integer.toHexString(quality));
2102                    return false;
2103                }
2104                quality = Math.max(realQuality, quality);
2105            }
2106            int length = getPasswordMinimumLength(null, userHandle);
2107            if (password.length() < length) {
2108                Slog.w(LOG_TAG, "resetPassword: password length " + password.length()
2109                        + " does not meet required length " + length);
2110                return false;
2111            }
2112            if (quality == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) {
2113                int letters = 0;
2114                int uppercase = 0;
2115                int lowercase = 0;
2116                int numbers = 0;
2117                int symbols = 0;
2118                int nonletter = 0;
2119                for (int i = 0; i < password.length(); i++) {
2120                    char c = password.charAt(i);
2121                    if (c >= 'A' && c <= 'Z') {
2122                        letters++;
2123                        uppercase++;
2124                    } else if (c >= 'a' && c <= 'z') {
2125                        letters++;
2126                        lowercase++;
2127                    } else if (c >= '0' && c <= '9') {
2128                        numbers++;
2129                        nonletter++;
2130                    } else {
2131                        symbols++;
2132                        nonletter++;
2133                    }
2134                }
2135                int neededLetters = getPasswordMinimumLetters(null, userHandle);
2136                if(letters < neededLetters) {
2137                    Slog.w(LOG_TAG, "resetPassword: number of letters " + letters
2138                            + " does not meet required number of letters " + neededLetters);
2139                    return false;
2140                }
2141                int neededNumbers = getPasswordMinimumNumeric(null, userHandle);
2142                if (numbers < neededNumbers) {
2143                    Slog.w(LOG_TAG, "resetPassword: number of numerical digits " + numbers
2144                            + " does not meet required number of numerical digits "
2145                            + neededNumbers);
2146                    return false;
2147                }
2148                int neededLowerCase = getPasswordMinimumLowerCase(null, userHandle);
2149                if (lowercase < neededLowerCase) {
2150                    Slog.w(LOG_TAG, "resetPassword: number of lowercase letters " + lowercase
2151                            + " does not meet required number of lowercase letters "
2152                            + neededLowerCase);
2153                    return false;
2154                }
2155                int neededUpperCase = getPasswordMinimumUpperCase(null, userHandle);
2156                if (uppercase < neededUpperCase) {
2157                    Slog.w(LOG_TAG, "resetPassword: number of uppercase letters " + uppercase
2158                            + " does not meet required number of uppercase letters "
2159                            + neededUpperCase);
2160                    return false;
2161                }
2162                int neededSymbols = getPasswordMinimumSymbols(null, userHandle);
2163                if (symbols < neededSymbols) {
2164                    Slog.w(LOG_TAG, "resetPassword: number of special symbols " + symbols
2165                            + " does not meet required number of special symbols " + neededSymbols);
2166                    return false;
2167                }
2168                int neededNonLetter = getPasswordMinimumNonLetter(null, userHandle);
2169                if (nonletter < neededNonLetter) {
2170                    Slog.w(LOG_TAG, "resetPassword: number of non-letter characters " + nonletter
2171                            + " does not meet required number of non-letter characters "
2172                            + neededNonLetter);
2173                    return false;
2174                }
2175            }
2176        }
2177
2178        int callingUid = Binder.getCallingUid();
2179        DevicePolicyData policy = getUserData(userHandle);
2180        if (policy.mPasswordOwner >= 0 && policy.mPasswordOwner != callingUid) {
2181            Slog.w(LOG_TAG, "resetPassword: already set by another uid and not entered by user");
2182            return false;
2183        }
2184
2185        // Don't do this with the lock held, because it is going to call
2186        // back in to the service.
2187        long ident = Binder.clearCallingIdentity();
2188        try {
2189            LockPatternUtils utils = new LockPatternUtils(mContext);
2190            utils.saveLockPassword(password, quality, false, userHandle);
2191            synchronized (this) {
2192                int newOwner = (flags&DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY)
2193                        != 0 ? callingUid : -1;
2194                if (policy.mPasswordOwner != newOwner) {
2195                    policy.mPasswordOwner = newOwner;
2196                    saveSettingsLocked(userHandle);
2197                }
2198            }
2199        } finally {
2200            Binder.restoreCallingIdentity(ident);
2201        }
2202
2203        return true;
2204    }
2205
2206    public void setMaximumTimeToLock(ComponentName who, long timeMs, int userHandle) {
2207        if (!mHasFeature) {
2208            return;
2209        }
2210        enforceCrossUserPermission(userHandle);
2211        synchronized (this) {
2212            if (who == null) {
2213                throw new NullPointerException("ComponentName is null");
2214            }
2215            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
2216                    DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
2217            if (ap.maximumTimeToUnlock != timeMs) {
2218                ap.maximumTimeToUnlock = timeMs;
2219                saveSettingsLocked(userHandle);
2220                updateMaximumTimeToLockLocked(getUserData(userHandle));
2221            }
2222        }
2223    }
2224
2225    void updateMaximumTimeToLockLocked(DevicePolicyData policy) {
2226        long timeMs = getMaximumTimeToLock(null, policy.mUserHandle);
2227        if (policy.mLastMaximumTimeToLock == timeMs) {
2228            return;
2229        }
2230
2231        long ident = Binder.clearCallingIdentity();
2232        try {
2233            if (timeMs <= 0) {
2234                timeMs = Integer.MAX_VALUE;
2235            } else {
2236                // Make sure KEEP_SCREEN_ON is disabled, since that
2237                // would allow bypassing of the maximum time to lock.
2238                Settings.Global.putInt(mContext.getContentResolver(),
2239                        Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
2240            }
2241
2242            policy.mLastMaximumTimeToLock = timeMs;
2243
2244            try {
2245                getIPowerManager().setMaximumScreenOffTimeoutFromDeviceAdmin((int)timeMs);
2246            } catch (RemoteException e) {
2247                Slog.w(LOG_TAG, "Failure talking with power manager", e);
2248            }
2249        } finally {
2250            Binder.restoreCallingIdentity(ident);
2251        }
2252    }
2253
2254    public long getMaximumTimeToLock(ComponentName who, int userHandle) {
2255        if (!mHasFeature) {
2256            return 0;
2257        }
2258        enforceCrossUserPermission(userHandle);
2259        synchronized (this) {
2260            long time = 0;
2261
2262            if (who != null) {
2263                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
2264                return admin != null ? admin.maximumTimeToUnlock : time;
2265            }
2266
2267            // Return strictest policy for this user and profiles that are visible from this user.
2268            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
2269            for (UserInfo userInfo : profiles) {
2270                DevicePolicyData policy = getUserData(userInfo.getUserHandle().getIdentifier());
2271                final int N = policy.mAdminList.size();
2272                for (int i=0; i<N; i++) {
2273                    ActiveAdmin admin = policy.mAdminList.get(i);
2274                    if (time == 0) {
2275                        time = admin.maximumTimeToUnlock;
2276                    } else if (admin.maximumTimeToUnlock != 0
2277                            && time > admin.maximumTimeToUnlock) {
2278                        time = admin.maximumTimeToUnlock;
2279                    }
2280                }
2281            }
2282            return time;
2283        }
2284    }
2285
2286    public void lockNow() {
2287        if (!mHasFeature) {
2288            return;
2289        }
2290        synchronized (this) {
2291            // This API can only be called by an active device admin,
2292            // so try to retrieve it to check that the caller is one.
2293            getActiveAdminForCallerLocked(null,
2294                    DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
2295            lockNowUnchecked();
2296        }
2297    }
2298
2299    private void lockNowUnchecked() {
2300        long ident = Binder.clearCallingIdentity();
2301        try {
2302            // Power off the display
2303            getIPowerManager().goToSleep(SystemClock.uptimeMillis(),
2304                    PowerManager.GO_TO_SLEEP_REASON_DEVICE_ADMIN, 0);
2305            // Ensure the device is locked
2306            getWindowManager().lockNow(null);
2307        } catch (RemoteException e) {
2308        } finally {
2309            Binder.restoreCallingIdentity(ident);
2310        }
2311    }
2312
2313    private boolean isExtStorageEncrypted() {
2314        String state = SystemProperties.get("vold.decrypt");
2315        return !"".equals(state);
2316    }
2317
2318    public boolean installCaCert(byte[] certBuffer) throws RemoteException {
2319        mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
2320        KeyChainConnection keyChainConnection = null;
2321        byte[] pemCert;
2322        try {
2323            X509Certificate cert = parseCert(certBuffer);
2324            pemCert =  Credentials.convertToPem(cert);
2325        } catch (CertificateException ce) {
2326            Log.e(LOG_TAG, "Problem converting cert", ce);
2327            return false;
2328        } catch (IOException ioe) {
2329            Log.e(LOG_TAG, "Problem reading cert", ioe);
2330            return false;
2331        }
2332        try {
2333            keyChainConnection = KeyChain.bind(mContext);
2334            try {
2335                keyChainConnection.getService().installCaCertificate(pemCert);
2336                return true;
2337            } finally {
2338                if (keyChainConnection != null) {
2339                    keyChainConnection.close();
2340                    keyChainConnection = null;
2341                }
2342            }
2343        } catch (InterruptedException e1) {
2344            Log.w(LOG_TAG, "installCaCertsToKeyChain(): ", e1);
2345            Thread.currentThread().interrupt();
2346        }
2347        return false;
2348    }
2349
2350    private static X509Certificate parseCert(byte[] certBuffer)
2351            throws CertificateException, IOException {
2352        CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
2353        return (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(
2354                certBuffer));
2355    }
2356
2357    public void uninstallCaCert(final byte[] certBuffer) {
2358        mContext.enforceCallingOrSelfPermission(MANAGE_CA_CERTIFICATES, null);
2359        TrustedCertificateStore certStore = new TrustedCertificateStore();
2360        String alias = null;
2361        try {
2362            X509Certificate cert = parseCert(certBuffer);
2363            alias = certStore.getCertificateAlias(cert);
2364        } catch (CertificateException ce) {
2365            Log.e(LOG_TAG, "Problem creating X509Certificate", ce);
2366            return;
2367        } catch (IOException ioe) {
2368            Log.e(LOG_TAG, "Problem reading certificate", ioe);
2369            return;
2370        }
2371        try {
2372            KeyChainConnection keyChainConnection = KeyChain.bind(mContext);
2373            IKeyChainService service = keyChainConnection.getService();
2374            try {
2375                service.deleteCaCertificate(alias);
2376            } catch (RemoteException e) {
2377                Log.e(LOG_TAG, "from CaCertUninstaller: ", e);
2378            } finally {
2379                keyChainConnection.close();
2380                keyChainConnection = null;
2381            }
2382        } catch (InterruptedException ie) {
2383            Log.w(LOG_TAG, "CaCertUninstaller: ", ie);
2384            Thread.currentThread().interrupt();
2385        }
2386    }
2387
2388    void wipeDataLocked(int flags) {
2389        // If the SD card is encrypted and non-removable, we have to force a wipe.
2390        boolean forceExtWipe = !Environment.isExternalStorageRemovable() && isExtStorageEncrypted();
2391        boolean wipeExtRequested = (flags&DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0;
2392
2393        // Note: we can only do the wipe via ExternalStorageFormatter if the volume is not emulated.
2394        if ((forceExtWipe || wipeExtRequested) && !Environment.isExternalStorageEmulated()) {
2395            Intent intent = new Intent(ExternalStorageFormatter.FORMAT_AND_FACTORY_RESET);
2396            intent.putExtra(ExternalStorageFormatter.EXTRA_ALWAYS_RESET, true);
2397            intent.setComponent(ExternalStorageFormatter.COMPONENT_NAME);
2398            mWakeLock.acquire(10000);
2399            mContext.startService(intent);
2400        } else {
2401            try {
2402                RecoverySystem.rebootWipeUserData(mContext);
2403            } catch (IOException e) {
2404                Slog.w(LOG_TAG, "Failed requesting data wipe", e);
2405            }
2406        }
2407    }
2408
2409    public void wipeData(int flags, final int userHandle) {
2410        if (!mHasFeature) {
2411            return;
2412        }
2413        enforceCrossUserPermission(userHandle);
2414        if ((flags & DevicePolicyManager.WIPE_EXTERNAL_STORAGE) != 0) {
2415            enforceNotManagedProfile(userHandle, "wipe external storage");
2416        }
2417        synchronized (this) {
2418            // This API can only be called by an active device admin,
2419            // so try to retrieve it to check that the caller is one.
2420            getActiveAdminForCallerLocked(null,
2421                    DeviceAdminInfo.USES_POLICY_WIPE_DATA);
2422            long ident = Binder.clearCallingIdentity();
2423            try {
2424                wipeDeviceOrUserLocked(flags, userHandle);
2425            } finally {
2426                Binder.restoreCallingIdentity(ident);
2427            }
2428        }
2429    }
2430
2431    private void wipeDeviceOrUserLocked(int flags, final int userHandle) {
2432        if (userHandle == UserHandle.USER_OWNER) {
2433            wipeDataLocked(flags);
2434        } else {
2435            lockNowUnchecked();
2436            mHandler.post(new Runnable() {
2437                public void run() {
2438                    try {
2439                        ActivityManagerNative.getDefault().switchUser(UserHandle.USER_OWNER);
2440                        (mUserManager)
2441                                .removeUser(userHandle);
2442                    } catch (RemoteException re) {
2443                        // Shouldn't happen
2444                    }
2445                }
2446            });
2447        }
2448    }
2449
2450    public void getRemoveWarning(ComponentName comp, final RemoteCallback result, int userHandle) {
2451        if (!mHasFeature) {
2452            return;
2453        }
2454        enforceCrossUserPermission(userHandle);
2455        mContext.enforceCallingOrSelfPermission(
2456                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
2457
2458        synchronized (this) {
2459            ActiveAdmin admin = getActiveAdminUncheckedLocked(comp, userHandle);
2460            if (admin == null) {
2461                try {
2462                    result.sendResult(null);
2463                } catch (RemoteException e) {
2464                }
2465                return;
2466            }
2467            Intent intent = new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED);
2468            intent.setComponent(admin.info.getComponent());
2469            mContext.sendOrderedBroadcastAsUser(intent, new UserHandle(userHandle),
2470                    null, new BroadcastReceiver() {
2471                @Override
2472                public void onReceive(Context context, Intent intent) {
2473                    try {
2474                        result.sendResult(getResultExtras(false));
2475                    } catch (RemoteException e) {
2476                    }
2477                }
2478            }, null, Activity.RESULT_OK, null, null);
2479        }
2480    }
2481
2482    public void setActivePasswordState(int quality, int length, int letters, int uppercase,
2483            int lowercase, int numbers, int symbols, int nonletter, int userHandle) {
2484        if (!mHasFeature) {
2485            return;
2486        }
2487        enforceCrossUserPermission(userHandle);
2488        enforceNotManagedProfile(userHandle, "set the active password");
2489
2490        mContext.enforceCallingOrSelfPermission(
2491                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
2492        DevicePolicyData p = getUserData(userHandle);
2493
2494        validateQualityConstant(quality);
2495
2496        synchronized (this) {
2497            if (p.mActivePasswordQuality != quality || p.mActivePasswordLength != length
2498                    || p.mFailedPasswordAttempts != 0 || p.mActivePasswordLetters != letters
2499                    || p.mActivePasswordUpperCase != uppercase
2500                    || p.mActivePasswordLowerCase != lowercase
2501                    || p.mActivePasswordNumeric != numbers
2502                    || p.mActivePasswordSymbols != symbols
2503                    || p.mActivePasswordNonLetter != nonletter) {
2504                long ident = Binder.clearCallingIdentity();
2505                try {
2506                    p.mActivePasswordQuality = quality;
2507                    p.mActivePasswordLength = length;
2508                    p.mActivePasswordLetters = letters;
2509                    p.mActivePasswordLowerCase = lowercase;
2510                    p.mActivePasswordUpperCase = uppercase;
2511                    p.mActivePasswordNumeric = numbers;
2512                    p.mActivePasswordSymbols = symbols;
2513                    p.mActivePasswordNonLetter = nonletter;
2514                    p.mFailedPasswordAttempts = 0;
2515                    saveSettingsLocked(userHandle);
2516                    updatePasswordExpirationsLocked(userHandle);
2517                    setExpirationAlarmCheckLocked(mContext, p);
2518                    sendAdminCommandToSelfAndProfilesLocked(
2519                            DeviceAdminReceiver.ACTION_PASSWORD_CHANGED,
2520                            DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD, userHandle);
2521                } finally {
2522                    Binder.restoreCallingIdentity(ident);
2523                }
2524            }
2525        }
2526    }
2527
2528    /**
2529     * Called any time the device password is updated. Resets all password expiration clocks.
2530     */
2531    private void updatePasswordExpirationsLocked(int userHandle) {
2532            List<UserInfo> profiles = mUserManager.getProfiles(userHandle);
2533            for (UserInfo userInfo : profiles) {
2534                int profileId = userInfo.getUserHandle().getIdentifier();
2535                DevicePolicyData policy = getUserData(profileId);
2536                final int N = policy.mAdminList.size();
2537                if (N > 0) {
2538                    for (int i=0; i<N; i++) {
2539                        ActiveAdmin admin = policy.mAdminList.get(i);
2540                        if (admin.info.usesPolicy(DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD)) {
2541                            long timeout = admin.passwordExpirationTimeout;
2542                            long expiration = timeout > 0L ? (timeout + System.currentTimeMillis()) : 0L;
2543                            admin.passwordExpirationDate = expiration;
2544                        }
2545                    }
2546                }
2547                saveSettingsLocked(profileId);
2548            }
2549    }
2550
2551    public void reportFailedPasswordAttempt(int userHandle) {
2552        enforceCrossUserPermission(userHandle);
2553        enforceNotManagedProfile(userHandle, "report failed password attempt");
2554        mContext.enforceCallingOrSelfPermission(
2555                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
2556
2557        synchronized (this) {
2558            DevicePolicyData policy = getUserData(userHandle);
2559            long ident = Binder.clearCallingIdentity();
2560            try {
2561                policy.mFailedPasswordAttempts++;
2562                saveSettingsLocked(userHandle);
2563                if (mHasFeature) {
2564                    int max = getMaximumFailedPasswordsForWipe(null, userHandle);
2565                    if (max > 0 && policy.mFailedPasswordAttempts >= max) {
2566                        wipeDeviceOrUserLocked(0, userHandle);
2567                    }
2568                    sendAdminCommandToSelfAndProfilesLocked(
2569                            DeviceAdminReceiver.ACTION_PASSWORD_FAILED,
2570                            DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
2571                }
2572            } finally {
2573                Binder.restoreCallingIdentity(ident);
2574            }
2575        }
2576    }
2577
2578    public void reportSuccessfulPasswordAttempt(int userHandle) {
2579        enforceCrossUserPermission(userHandle);
2580        mContext.enforceCallingOrSelfPermission(
2581                android.Manifest.permission.BIND_DEVICE_ADMIN, null);
2582
2583        synchronized (this) {
2584            DevicePolicyData policy = getUserData(userHandle);
2585            if (policy.mFailedPasswordAttempts != 0 || policy.mPasswordOwner >= 0) {
2586                long ident = Binder.clearCallingIdentity();
2587                try {
2588                    policy.mFailedPasswordAttempts = 0;
2589                    policy.mPasswordOwner = -1;
2590                    saveSettingsLocked(userHandle);
2591                    if (mHasFeature) {
2592                        sendAdminCommandToSelfAndProfilesLocked(
2593                                DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED,
2594                                DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, userHandle);
2595                    }
2596                } finally {
2597                    Binder.restoreCallingIdentity(ident);
2598                }
2599            }
2600        }
2601    }
2602
2603    public ComponentName setGlobalProxy(ComponentName who, String proxySpec,
2604            String exclusionList, int userHandle) {
2605        if (!mHasFeature) {
2606            return null;
2607        }
2608        enforceCrossUserPermission(userHandle);
2609        synchronized(this) {
2610            if (who == null) {
2611                throw new NullPointerException("ComponentName is null");
2612            }
2613
2614            // Only check if owner has set global proxy. We don't allow other users to set it.
2615            DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
2616            ActiveAdmin admin = getActiveAdminForCallerLocked(who,
2617                    DeviceAdminInfo.USES_POLICY_SETS_GLOBAL_PROXY);
2618
2619            // Scan through active admins and find if anyone has already
2620            // set the global proxy.
2621            Set<ComponentName> compSet = policy.mAdminMap.keySet();
2622            for (ComponentName component : compSet) {
2623                ActiveAdmin ap = policy.mAdminMap.get(component);
2624                if ((ap.specifiesGlobalProxy) && (!component.equals(who))) {
2625                    // Another admin already sets the global proxy
2626                    // Return it to the caller.
2627                    return component;
2628                }
2629            }
2630
2631            // If the user is not the owner, don't set the global proxy. Fail silently.
2632            if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
2633                Slog.w(LOG_TAG, "Only the owner is allowed to set the global proxy. User "
2634                        + userHandle + " is not permitted.");
2635                return null;
2636            }
2637            if (proxySpec == null) {
2638                admin.specifiesGlobalProxy = false;
2639                admin.globalProxySpec = null;
2640                admin.globalProxyExclusionList = null;
2641            } else {
2642
2643                admin.specifiesGlobalProxy = true;
2644                admin.globalProxySpec = proxySpec;
2645                admin.globalProxyExclusionList = exclusionList;
2646            }
2647
2648            // Reset the global proxy accordingly
2649            // Do this using system permissions, as apps cannot write to secure settings
2650            long origId = Binder.clearCallingIdentity();
2651            try {
2652                resetGlobalProxyLocked(policy);
2653            } finally {
2654                Binder.restoreCallingIdentity(origId);
2655            }
2656            return null;
2657        }
2658    }
2659
2660    public ComponentName getGlobalProxyAdmin(int userHandle) {
2661        if (!mHasFeature) {
2662            return null;
2663        }
2664        enforceCrossUserPermission(userHandle);
2665        synchronized(this) {
2666            DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
2667            // Scan through active admins and find if anyone has already
2668            // set the global proxy.
2669            final int N = policy.mAdminList.size();
2670            for (int i = 0; i < N; i++) {
2671                ActiveAdmin ap = policy.mAdminList.get(i);
2672                if (ap.specifiesGlobalProxy) {
2673                    // Device admin sets the global proxy
2674                    // Return it to the caller.
2675                    return ap.info.getComponent();
2676                }
2677            }
2678        }
2679        // No device admin sets the global proxy.
2680        return null;
2681    }
2682
2683    private void resetGlobalProxyLocked(DevicePolicyData policy) {
2684        final int N = policy.mAdminList.size();
2685        for (int i = 0; i < N; i++) {
2686            ActiveAdmin ap = policy.mAdminList.get(i);
2687            if (ap.specifiesGlobalProxy) {
2688                saveGlobalProxyLocked(ap.globalProxySpec, ap.globalProxyExclusionList);
2689                return;
2690            }
2691        }
2692        // No device admins defining global proxies - reset global proxy settings to none
2693        saveGlobalProxyLocked(null, null);
2694    }
2695
2696    private void saveGlobalProxyLocked(String proxySpec, String exclusionList) {
2697        if (exclusionList == null) {
2698            exclusionList = "";
2699        }
2700        if (proxySpec == null) {
2701            proxySpec = "";
2702        }
2703        // Remove white spaces
2704        proxySpec = proxySpec.trim();
2705        String data[] = proxySpec.split(":");
2706        int proxyPort = 8080;
2707        if (data.length > 1) {
2708            try {
2709                proxyPort = Integer.parseInt(data[1]);
2710            } catch (NumberFormatException e) {}
2711        }
2712        exclusionList = exclusionList.trim();
2713        ContentResolver res = mContext.getContentResolver();
2714
2715        ProxyInfo proxyProperties = new ProxyInfo(data[0], proxyPort, exclusionList);
2716        if (!proxyProperties.isValid()) {
2717            Slog.e(LOG_TAG, "Invalid proxy properties, ignoring: " + proxyProperties.toString());
2718            return;
2719        }
2720        Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_HOST, data[0]);
2721        Settings.Global.putInt(res, Settings.Global.GLOBAL_HTTP_PROXY_PORT, proxyPort);
2722        Settings.Global.putString(res, Settings.Global.GLOBAL_HTTP_PROXY_EXCLUSION_LIST,
2723                exclusionList);
2724    }
2725
2726    /**
2727     * Set the storage encryption request for a single admin.  Returns the new total request
2728     * status (for all admins).
2729     */
2730    public int setStorageEncryption(ComponentName who, boolean encrypt, int userHandle) {
2731        if (!mHasFeature) {
2732            return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
2733        }
2734        enforceCrossUserPermission(userHandle);
2735        synchronized (this) {
2736            // Check for permissions
2737            if (who == null) {
2738                throw new NullPointerException("ComponentName is null");
2739            }
2740            // Only owner can set storage encryption
2741            if (userHandle != UserHandle.USER_OWNER
2742                    || UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
2743                Slog.w(LOG_TAG, "Only owner is allowed to set storage encryption. User "
2744                        + UserHandle.getCallingUserId() + " is not permitted.");
2745                return 0;
2746            }
2747
2748            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
2749                    DeviceAdminInfo.USES_ENCRYPTED_STORAGE);
2750
2751            // Quick exit:  If the filesystem does not support encryption, we can exit early.
2752            if (!isEncryptionSupported()) {
2753                return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
2754            }
2755
2756            // (1) Record the value for the admin so it's sticky
2757            if (ap.encryptionRequested != encrypt) {
2758                ap.encryptionRequested = encrypt;
2759                saveSettingsLocked(userHandle);
2760            }
2761
2762            DevicePolicyData policy = getUserData(UserHandle.USER_OWNER);
2763            // (2) Compute "max" for all admins
2764            boolean newRequested = false;
2765            final int N = policy.mAdminList.size();
2766            for (int i = 0; i < N; i++) {
2767                newRequested |= policy.mAdminList.get(i).encryptionRequested;
2768            }
2769
2770            // Notify OS of new request
2771            setEncryptionRequested(newRequested);
2772
2773            // Return the new global request status
2774            return newRequested
2775                    ? DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE
2776                    : DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
2777        }
2778    }
2779
2780    /**
2781     * Get the current storage encryption request status for a given admin, or aggregate of all
2782     * active admins.
2783     */
2784    public boolean getStorageEncryption(ComponentName who, int userHandle) {
2785        if (!mHasFeature) {
2786            return false;
2787        }
2788        enforceCrossUserPermission(userHandle);
2789        synchronized (this) {
2790            // Check for permissions if a particular caller is specified
2791            if (who != null) {
2792                // When checking for a single caller, status is based on caller's request
2793                ActiveAdmin ap = getActiveAdminUncheckedLocked(who, userHandle);
2794                return ap != null ? ap.encryptionRequested : false;
2795            }
2796
2797            // If no particular caller is specified, return the aggregate set of requests.
2798            // This is short circuited by returning true on the first hit.
2799            DevicePolicyData policy = getUserData(userHandle);
2800            final int N = policy.mAdminList.size();
2801            for (int i = 0; i < N; i++) {
2802                if (policy.mAdminList.get(i).encryptionRequested) {
2803                    return true;
2804                }
2805            }
2806            return false;
2807        }
2808    }
2809
2810    /**
2811     * Get the current encryption status of the device.
2812     */
2813    public int getStorageEncryptionStatus(int userHandle) {
2814        if (!mHasFeature) {
2815            // Ok to return current status.
2816        }
2817        enforceCrossUserPermission(userHandle);
2818        return getEncryptionStatus();
2819    }
2820
2821    /**
2822     * Hook to low-levels:  This should report if the filesystem supports encrypted storage.
2823     */
2824    private boolean isEncryptionSupported() {
2825        // Note, this can be implemented as
2826        //   return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
2827        // But is provided as a separate internal method if there's a faster way to do a
2828        // simple check for supported-or-not.
2829        return getEncryptionStatus() != DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
2830    }
2831
2832    /**
2833     * Hook to low-levels:  Reporting the current status of encryption.
2834     * @return A value such as {@link DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED} or
2835     * {@link DevicePolicyManager#ENCRYPTION_STATUS_INACTIVE} or
2836     * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE}.
2837     */
2838    private int getEncryptionStatus() {
2839        String status = SystemProperties.get("ro.crypto.state", "unsupported");
2840        if ("encrypted".equalsIgnoreCase(status)) {
2841            return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
2842        } else if ("unencrypted".equalsIgnoreCase(status)) {
2843            return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
2844        } else {
2845            return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
2846        }
2847    }
2848
2849    /**
2850     * Hook to low-levels:  If needed, record the new admin setting for encryption.
2851     */
2852    private void setEncryptionRequested(boolean encrypt) {
2853    }
2854
2855    /**
2856     * The system property used to share the state of the camera. The native camera service
2857     * is expected to read this property and act accordingly.
2858     */
2859    public static final String SYSTEM_PROP_DISABLE_CAMERA = "sys.secpolicy.camera.disabled";
2860
2861    /**
2862     * Disables all device cameras according to the specified admin.
2863     */
2864    public void setCameraDisabled(ComponentName who, boolean disabled, int userHandle) {
2865        if (!mHasFeature) {
2866            return;
2867        }
2868        enforceCrossUserPermission(userHandle);
2869        enforceNotManagedProfile(userHandle, "enable/disable cameras");
2870        synchronized (this) {
2871            if (who == null) {
2872                throw new NullPointerException("ComponentName is null");
2873            }
2874            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
2875                    DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA);
2876            if (ap.disableCamera != disabled) {
2877                ap.disableCamera = disabled;
2878                saveSettingsLocked(userHandle);
2879            }
2880            syncDeviceCapabilitiesLocked(getUserData(userHandle));
2881        }
2882    }
2883
2884    /**
2885     * Gets whether or not all device cameras are disabled for a given admin, or disabled for any
2886     * active admins.
2887     */
2888    public boolean getCameraDisabled(ComponentName who, int userHandle) {
2889        if (!mHasFeature) {
2890            return false;
2891        }
2892        synchronized (this) {
2893            if (who != null) {
2894                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
2895                return (admin != null) ? admin.disableCamera : false;
2896            }
2897
2898            DevicePolicyData policy = getUserData(userHandle);
2899            // Determine whether or not the device camera is disabled for any active admins.
2900            final int N = policy.mAdminList.size();
2901            for (int i = 0; i < N; i++) {
2902                ActiveAdmin admin = policy.mAdminList.get(i);
2903                if (admin.disableCamera) {
2904                    return true;
2905                }
2906            }
2907            return false;
2908        }
2909    }
2910
2911    /**
2912     * Selectively disable keyguard features.
2913     */
2914    public void setKeyguardDisabledFeatures(ComponentName who, int which, int userHandle) {
2915        if (!mHasFeature) {
2916            return;
2917        }
2918        enforceCrossUserPermission(userHandle);
2919        enforceNotManagedProfile(userHandle, "disable keyguard features");
2920        synchronized (this) {
2921            if (who == null) {
2922                throw new NullPointerException("ComponentName is null");
2923            }
2924            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
2925                    DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES);
2926            if (ap.disabledKeyguardFeatures != which) {
2927                ap.disabledKeyguardFeatures = which;
2928                saveSettingsLocked(userHandle);
2929            }
2930            syncDeviceCapabilitiesLocked(getUserData(userHandle));
2931        }
2932    }
2933
2934    /**
2935     * Gets the disabled state for features in keyguard for the given admin,
2936     * or the aggregate of all active admins if who is null.
2937     */
2938    public int getKeyguardDisabledFeatures(ComponentName who, int userHandle) {
2939        if (!mHasFeature) {
2940            return 0;
2941        }
2942        enforceCrossUserPermission(userHandle);
2943        synchronized (this) {
2944            if (who != null) {
2945                ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle);
2946                return (admin != null) ? admin.disabledKeyguardFeatures : 0;
2947            }
2948
2949            // Determine which keyguard features are disabled for any active admins.
2950            DevicePolicyData policy = getUserData(userHandle);
2951            final int N = policy.mAdminList.size();
2952            int which = 0;
2953            for (int i = 0; i < N; i++) {
2954                ActiveAdmin admin = policy.mAdminList.get(i);
2955                which |= admin.disabledKeyguardFeatures;
2956            }
2957            return which;
2958        }
2959    }
2960
2961    @Override
2962    public boolean setDeviceOwner(String packageName, String ownerName) {
2963        if (!mHasFeature) {
2964            return false;
2965        }
2966        if (packageName == null
2967                || !DeviceOwner.isInstalled(packageName, mContext.getPackageManager())) {
2968            throw new IllegalArgumentException("Invalid package name " + packageName
2969                    + " for device owner");
2970        }
2971        synchronized (this) {
2972            if (isDeviceProvisioned()) {
2973                throw new IllegalStateException(
2974                        "Trying to set device owner but device is already provisioned.");
2975            }
2976
2977            if (mDeviceOwner != null && mDeviceOwner.hasDeviceOwner()) {
2978                throw new IllegalStateException(
2979                        "Trying to set device owner but device owner is already set.");
2980            }
2981
2982            long token = Binder.clearCallingIdentity();
2983            try {
2984                mAppOpsService.setDeviceOwner(packageName);
2985            } catch (RemoteException e) {
2986                Log.w(LOG_TAG, "Unable to notify AppOpsService of DeviceOwner", e);
2987            } finally {
2988                Binder.restoreCallingIdentity(token);
2989            }
2990            if (mDeviceOwner == null) {
2991                // Device owner is not set and does not exist, set it.
2992                mDeviceOwner = DeviceOwner.createWithDeviceOwner(packageName, ownerName);
2993                mDeviceOwner.writeOwnerFile();
2994                return true;
2995            } else {
2996                // Device owner is not set but a profile owner exists, update Device owner state.
2997                mDeviceOwner.setDeviceOwner(packageName, ownerName);
2998                mDeviceOwner.writeOwnerFile();
2999                return true;
3000            }
3001        }
3002    }
3003
3004    @Override
3005    public boolean isDeviceOwner(String packageName) {
3006        if (!mHasFeature) {
3007            return false;
3008        }
3009        synchronized (this) {
3010            return mDeviceOwner != null
3011                    && mDeviceOwner.hasDeviceOwner()
3012                    && mDeviceOwner.getDeviceOwnerPackageName().equals(packageName);
3013        }
3014    }
3015
3016    @Override
3017    public String getDeviceOwner() {
3018        if (!mHasFeature) {
3019            return null;
3020        }
3021        synchronized (this) {
3022            if (mDeviceOwner != null && mDeviceOwner.hasDeviceOwner()) {
3023                return mDeviceOwner.getDeviceOwnerPackageName();
3024            }
3025        }
3026        return null;
3027    }
3028
3029    @Override
3030    public String getDeviceOwnerName() {
3031        if (!mHasFeature) {
3032            return null;
3033        }
3034        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
3035        synchronized (this) {
3036            if (mDeviceOwner != null) {
3037                return mDeviceOwner.getDeviceOwnerName();
3038            }
3039        }
3040        return null;
3041    }
3042
3043    @Override
3044    public boolean setProfileOwner(String packageName, String ownerName, int userHandle) {
3045        if (!mHasFeature) {
3046            return false;
3047        }
3048        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
3049
3050        if (mUserManager.getUserInfo(userHandle) == null) {
3051            // User doesn't exist.
3052            throw new IllegalArgumentException(
3053                    "Attempted to set profile owner for invalid userId: " + userHandle);
3054        }
3055
3056        if (packageName == null
3057                || !DeviceOwner.isInstalledForUser(packageName, userHandle)) {
3058            throw new IllegalArgumentException("Package name " + packageName
3059                    + " not installed for userId:" + userHandle);
3060        }
3061        synchronized (this) {
3062            if (isUserSetupComplete(userHandle)) {
3063                throw new IllegalStateException(
3064                        "Trying to set profile owner but user is already set-up.");
3065            }
3066            long token = Binder.clearCallingIdentity();
3067            try {
3068                mAppOpsService.setProfileOwner(packageName, userHandle);
3069            } catch (RemoteException e) {
3070                Log.w(LOG_TAG, "Unable to notify AppOpsService of ProfileOwner", e);
3071            } finally {
3072                Binder.restoreCallingIdentity(token);
3073            }
3074            if (mDeviceOwner == null) {
3075                // Device owner state does not exist, create it.
3076                mDeviceOwner = DeviceOwner.createWithProfileOwner(packageName, ownerName,
3077                        userHandle);
3078                mDeviceOwner.writeOwnerFile();
3079                return true;
3080            } else {
3081                // Device owner already exists, update it.
3082                mDeviceOwner.setProfileOwner(packageName, ownerName, userHandle);
3083                mDeviceOwner.writeOwnerFile();
3084                return true;
3085            }
3086        }
3087    }
3088
3089    @Override
3090    public void setProfileEnabled(ComponentName who) {
3091        if (!mHasFeature) {
3092            return;
3093        }
3094        synchronized (this) {
3095            // Check for permissions
3096            if (who == null) {
3097                throw new NullPointerException("ComponentName is null");
3098            }
3099            // Check if this is the profile owner who is calling
3100            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3101            int userId = UserHandle.getCallingUserId();
3102            Slog.d(LOG_TAG, "Enabling the profile for: " + userId);
3103
3104            long id = Binder.clearCallingIdentity();
3105            try {
3106                mUserManager.setUserEnabled(userId);
3107                Intent intent = new Intent(Intent.ACTION_MANAGED_PROFILE_ADDED);
3108                intent.putExtra(Intent.EXTRA_USER, new UserHandle(UserHandle.getCallingUserId()));
3109                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY |
3110                        Intent.FLAG_RECEIVER_FOREGROUND);
3111                mContext.sendBroadcastAsUser(intent, UserHandle.OWNER);
3112            } finally {
3113                restoreCallingIdentity(id);
3114            }
3115        }
3116    }
3117
3118    @Override
3119    public String getProfileOwner(int userHandle) {
3120        if (!mHasFeature) {
3121            return null;
3122        }
3123
3124        synchronized (this) {
3125            if (mDeviceOwner != null) {
3126                return mDeviceOwner.getProfileOwnerPackageName(userHandle);
3127            }
3128        }
3129        return null;
3130    }
3131
3132    @Override
3133    public String getProfileOwnerName(int userHandle) {
3134        if (!mHasFeature) {
3135            return null;
3136        }
3137        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
3138
3139        synchronized (this) {
3140            if (mDeviceOwner != null) {
3141                return mDeviceOwner.getProfileOwnerName(userHandle);
3142            }
3143        }
3144        return null;
3145    }
3146
3147    private boolean isDeviceProvisioned() {
3148        return Settings.Global.getInt(mContext.getContentResolver(),
3149                Settings.Global.DEVICE_PROVISIONED, 0) > 0;
3150    }
3151
3152    private boolean isUserSetupComplete(int userId) {
3153        return Settings.Secure.getIntForUser(mContext.getContentResolver(),
3154                Settings.Secure.USER_SETUP_COMPLETE, 0, userId) > 0;
3155    }
3156
3157    private void enforceCrossUserPermission(int userHandle) {
3158        if (userHandle < 0) {
3159            throw new IllegalArgumentException("Invalid userId " + userHandle);
3160        }
3161        final int callingUid = Binder.getCallingUid();
3162        if (userHandle == UserHandle.getUserId(callingUid)) return;
3163        if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
3164            mContext.enforceCallingOrSelfPermission(
3165                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, "Must be system or have"
3166                    + " INTERACT_ACROSS_USERS_FULL permission");
3167        }
3168    }
3169
3170    private void enforceNotManagedProfile(int userHandle, String message) {
3171        if(isManagedProfile(userHandle)) {
3172            throw new SecurityException("You can not " + message + " for a managed profile. ");
3173        }
3174    }
3175
3176    private UserInfo getProfileParent(int userHandle) {
3177        long ident = Binder.clearCallingIdentity();
3178        try {
3179            return mUserManager.getProfileParent(userHandle);
3180        } finally {
3181            Binder.restoreCallingIdentity(ident);
3182        }
3183    }
3184
3185    private boolean isManagedProfile(int userHandle) {
3186        long ident = Binder.clearCallingIdentity();
3187        try {
3188            return mUserManager.getUserInfo(userHandle).isManagedProfile();
3189        } finally {
3190            Binder.restoreCallingIdentity(ident);
3191        }
3192    }
3193
3194    private void enableIfNecessary(String packageName, int userId) {
3195        try {
3196            IPackageManager ipm = AppGlobals.getPackageManager();
3197            ApplicationInfo ai = ipm.getApplicationInfo(packageName,
3198                    PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
3199                    userId);
3200            if (ai.enabledSetting
3201                    == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
3202                ipm.setApplicationEnabledSetting(packageName,
3203                        PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
3204                        PackageManager.DONT_KILL_APP, userId, "DevicePolicyManager");
3205            }
3206        } catch (RemoteException e) {
3207        }
3208    }
3209
3210    @Override
3211    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
3212        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
3213                != PackageManager.PERMISSION_GRANTED) {
3214
3215            pw.println("Permission Denial: can't dump DevicePolicyManagerService from from pid="
3216                    + Binder.getCallingPid()
3217                    + ", uid=" + Binder.getCallingUid());
3218            return;
3219        }
3220
3221        final Printer p = new PrintWriterPrinter(pw);
3222
3223        synchronized (this) {
3224            p.println("Current Device Policy Manager state:");
3225
3226            int userCount = mUserData.size();
3227            for (int u = 0; u < userCount; u++) {
3228                DevicePolicyData policy = getUserData(mUserData.keyAt(u));
3229                p.println("  Enabled Device Admins (User " + policy.mUserHandle + "):");
3230                final int N = policy.mAdminList.size();
3231                for (int i=0; i<N; i++) {
3232                    ActiveAdmin ap = policy.mAdminList.get(i);
3233                    if (ap != null) {
3234                        pw.print("  "); pw.print(ap.info.getComponent().flattenToShortString());
3235                                pw.println(":");
3236                        ap.dump("    ", pw);
3237                    }
3238                }
3239
3240                pw.println(" ");
3241                pw.print("  mPasswordOwner="); pw.println(policy.mPasswordOwner);
3242            }
3243        }
3244    }
3245
3246    @Override
3247    public void addPersistentPreferredActivity(ComponentName who, IntentFilter filter,
3248            ComponentName activity) {
3249        synchronized (this) {
3250            if (who == null) {
3251                throw new NullPointerException("ComponentName is null");
3252            }
3253            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3254
3255            IPackageManager pm = AppGlobals.getPackageManager();
3256            long id = Binder.clearCallingIdentity();
3257            try {
3258                pm.addPersistentPreferredActivity(filter, activity, UserHandle.getCallingUserId());
3259            } catch (RemoteException re) {
3260                // Shouldn't happen
3261            } finally {
3262                restoreCallingIdentity(id);
3263            }
3264        }
3265    }
3266
3267    @Override
3268    public void clearPackagePersistentPreferredActivities(ComponentName who, String packageName) {
3269        synchronized (this) {
3270            if (who == null) {
3271                throw new NullPointerException("ComponentName is null");
3272            }
3273            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3274
3275            IPackageManager pm = AppGlobals.getPackageManager();
3276            long id = Binder.clearCallingIdentity();
3277            try {
3278                pm.clearPackagePersistentPreferredActivities(packageName, UserHandle.getCallingUserId());
3279            } catch (RemoteException re) {
3280                // Shouldn't happen
3281            } finally {
3282                restoreCallingIdentity(id);
3283            }
3284        }
3285    }
3286
3287    @Override
3288    public void setApplicationRestrictions(ComponentName who, String packageName, Bundle settings) {
3289        final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
3290
3291        synchronized (this) {
3292            if (who == null) {
3293                throw new NullPointerException("ComponentName is null");
3294            }
3295            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3296
3297            long id = Binder.clearCallingIdentity();
3298            try {
3299                mUserManager.setApplicationRestrictions(packageName, settings, userHandle);
3300            } finally {
3301                restoreCallingIdentity(id);
3302            }
3303        }
3304    }
3305
3306    public void addForwardingIntentFilter(ComponentName who, IntentFilter filter, int flags) {
3307        int callingUserId = UserHandle.getCallingUserId();
3308        synchronized (this) {
3309            if (who == null) {
3310                throw new NullPointerException("ComponentName is null");
3311            }
3312            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3313
3314            IPackageManager pm = AppGlobals.getPackageManager();
3315            long id = Binder.clearCallingIdentity();
3316            try {
3317                if ((flags & DevicePolicyManager.FLAG_TO_PRIMARY_USER) != 0) {
3318                    pm.addForwardingIntentFilter(filter, true /*removable*/, callingUserId,
3319                            UserHandle.USER_OWNER);
3320                }
3321                if ((flags & DevicePolicyManager.FLAG_TO_MANAGED_PROFILE) != 0) {
3322                    pm.addForwardingIntentFilter(filter, true /*removable*/, UserHandle.USER_OWNER,
3323                            callingUserId);
3324                }
3325            } catch (RemoteException re) {
3326                // Shouldn't happen
3327            } finally {
3328                restoreCallingIdentity(id);
3329            }
3330        }
3331    }
3332
3333    public void clearForwardingIntentFilters(ComponentName who) {
3334        int callingUserId = UserHandle.getCallingUserId();
3335        synchronized (this) {
3336            if (who == null) {
3337                throw new NullPointerException("ComponentName is null");
3338            }
3339            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3340            IPackageManager pm = AppGlobals.getPackageManager();
3341            long id = Binder.clearCallingIdentity();
3342            try {
3343                pm.clearForwardingIntentFilters(callingUserId);
3344                pm.clearForwardingIntentFilters(UserHandle.USER_OWNER);
3345            } catch (RemoteException re) {
3346                // Shouldn't happen
3347            } finally {
3348                restoreCallingIdentity(id);
3349            }
3350        }
3351    }
3352
3353    @Override
3354    public UserHandle createUser(ComponentName who, String name) {
3355        synchronized (this) {
3356            if (who == null) {
3357                throw new NullPointerException("ComponentName is null");
3358            }
3359            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
3360
3361            long id = Binder.clearCallingIdentity();
3362            try {
3363                UserInfo userInfo = mUserManager.createUser(name, 0 /* flags */);
3364                if (userInfo != null) {
3365                    return userInfo.getUserHandle();
3366                }
3367                return null;
3368            } finally {
3369                restoreCallingIdentity(id);
3370            }
3371        }
3372    }
3373
3374    @Override
3375    public boolean removeUser(ComponentName who, UserHandle userHandle) {
3376        synchronized (this) {
3377            if (who == null) {
3378                throw new NullPointerException("ComponentName is null");
3379            }
3380            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
3381
3382            long id = Binder.clearCallingIdentity();
3383            try {
3384                return mUserManager.removeUser(userHandle.getIdentifier());
3385            } finally {
3386                restoreCallingIdentity(id);
3387            }
3388        }
3389    }
3390
3391    @Override
3392    public Bundle getApplicationRestrictions(ComponentName who, String packageName) {
3393        final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
3394
3395        synchronized (this) {
3396            if (who == null) {
3397                throw new NullPointerException("ComponentName is null");
3398            }
3399            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3400
3401            long id = Binder.clearCallingIdentity();
3402            try {
3403                return mUserManager.getApplicationRestrictions(packageName, userHandle);
3404            } finally {
3405                restoreCallingIdentity(id);
3406            }
3407        }
3408    }
3409
3410    @Override
3411    public void setUserRestriction(ComponentName who, String key, boolean enabled) {
3412        final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId());
3413
3414        synchronized (this) {
3415            if (who == null) {
3416                throw new NullPointerException("ComponentName is null");
3417            }
3418            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3419
3420            long id = Binder.clearCallingIdentity();
3421            try {
3422                mUserManager.setUserRestriction(key, enabled, userHandle);
3423            } finally {
3424                restoreCallingIdentity(id);
3425            }
3426        }
3427    }
3428
3429    @Override
3430    public boolean setApplicationBlocked(ComponentName who, String packageName,
3431            boolean blocked) {
3432        int callingUserId = UserHandle.getCallingUserId();
3433        synchronized (this) {
3434            if (who == null) {
3435                throw new NullPointerException("ComponentName is null");
3436            }
3437            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3438
3439            long id = Binder.clearCallingIdentity();
3440            try {
3441                IPackageManager pm = AppGlobals.getPackageManager();
3442                return pm.setApplicationBlockedSettingAsUser(packageName, blocked, callingUserId);
3443            } catch (RemoteException re) {
3444                // shouldn't happen
3445                Slog.e(LOG_TAG, "Failed to setApplicationBlockedSetting", re);
3446            } finally {
3447                restoreCallingIdentity(id);
3448            }
3449            return false;
3450        }
3451    }
3452
3453    @Override
3454    public int setApplicationsBlocked(ComponentName who, Intent intent, boolean blocked) {
3455        int callingUserId = UserHandle.getCallingUserId();
3456        synchronized (this) {
3457            if (who == null) {
3458                throw new NullPointerException("ComponentName is null");
3459            }
3460            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3461
3462            long id = Binder.clearCallingIdentity();
3463            try {
3464                IPackageManager pm = AppGlobals.getPackageManager();
3465                List<ResolveInfo> activitiesToEnable = pm.queryIntentActivities(intent,
3466                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3467                        PackageManager.GET_DISABLED_COMPONENTS
3468                                | PackageManager.GET_UNINSTALLED_PACKAGES,
3469                        callingUserId);
3470
3471                if (DBG) Slog.d(LOG_TAG, "Enabling activities: " + activitiesToEnable);
3472                int numberOfAppsUnblocked = 0;
3473                if (activitiesToEnable != null) {
3474                    for (ResolveInfo info : activitiesToEnable) {
3475                        if (info.activityInfo != null) {
3476                            numberOfAppsUnblocked++;
3477                            pm.setApplicationBlockedSettingAsUser(info.activityInfo.packageName,
3478                                    blocked, callingUserId);
3479                        }
3480                    }
3481                }
3482                return numberOfAppsUnblocked;
3483            } catch (RemoteException re) {
3484                // shouldn't happen
3485                Slog.e(LOG_TAG, "Failed to setApplicationsBlockedSettingsWithIntent", re);
3486            } finally {
3487                restoreCallingIdentity(id);
3488            }
3489            return 0;
3490        }
3491    }
3492
3493    @Override
3494    public boolean isApplicationBlocked(ComponentName who, String packageName) {
3495        int callingUserId = UserHandle.getCallingUserId();
3496        synchronized (this) {
3497            if (who == null) {
3498                throw new NullPointerException("ComponentName is null");
3499            }
3500            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3501
3502            long id = Binder.clearCallingIdentity();
3503            try {
3504                IPackageManager pm = AppGlobals.getPackageManager();
3505                return pm.getApplicationBlockedSettingAsUser(packageName, callingUserId);
3506            } catch (RemoteException re) {
3507                // shouldn't happen
3508                Slog.e(LOG_TAG, "Failed to getApplicationBlockedSettingAsUser", re);
3509            } finally {
3510                restoreCallingIdentity(id);
3511            }
3512            return false;
3513        }
3514    }
3515
3516    @Override
3517    public void enableSystemApp(ComponentName who, String packageName) {
3518        synchronized (this) {
3519            if (who == null) {
3520                throw new NullPointerException("ComponentName is null");
3521            }
3522            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3523
3524            int userId = UserHandle.getCallingUserId();
3525            long id = Binder.clearCallingIdentity();
3526
3527            try {
3528                UserManager um = UserManager.get(mContext);
3529                if (!um.getUserInfo(userId).isManagedProfile()) {
3530                    throw new IllegalStateException(
3531                            "Only call this method from a managed profile.");
3532                }
3533
3534                // TODO: Use UserManager::getProfileParent when available.
3535                UserInfo primaryUser = um.getUserInfo(UserHandle.USER_OWNER);
3536
3537                if (DBG) {
3538                    Slog.v(LOG_TAG, "installing " + packageName + " for "
3539                            + userId);
3540                }
3541
3542                IPackageManager pm = AppGlobals.getPackageManager();
3543                if (!isSystemApp(pm, packageName, primaryUser.id)) {
3544                    throw new IllegalArgumentException("Only system apps can be enabled this way.");
3545                }
3546
3547                // Install the app.
3548                pm.installExistingPackageAsUser(packageName, userId);
3549
3550            } catch (RemoteException re) {
3551                // shouldn't happen
3552                Slog.wtf(LOG_TAG, "Failed to install " + packageName, re);
3553            } finally {
3554                restoreCallingIdentity(id);
3555            }
3556        }
3557    }
3558
3559    @Override
3560    public int enableSystemAppWithIntent(ComponentName who, Intent intent) {
3561        synchronized (this) {
3562            if (who == null) {
3563                throw new NullPointerException("ComponentName is null");
3564            }
3565
3566            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3567
3568            int userId = UserHandle.getCallingUserId();
3569            long id = Binder.clearCallingIdentity();
3570
3571            try {
3572                UserManager um = UserManager.get(mContext);
3573                if (!um.getUserInfo(userId).isManagedProfile()) {
3574                    throw new IllegalStateException(
3575                            "Only call this method from a managed profile.");
3576                }
3577
3578                // TODO: Use UserManager::getProfileParent when available.
3579                UserInfo primaryUser = um.getUserInfo(UserHandle.USER_OWNER);
3580
3581                IPackageManager pm = AppGlobals.getPackageManager();
3582                List<ResolveInfo> activitiesToEnable = pm.queryIntentActivities(intent,
3583                        intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3584                        0, // no flags
3585                        primaryUser.id);
3586
3587                if (DBG) Slog.d(LOG_TAG, "Enabling system activities: " + activitiesToEnable);
3588                int numberOfAppsInstalled = 0;
3589                if (activitiesToEnable != null) {
3590                    for (ResolveInfo info : activitiesToEnable) {
3591                        if (info.activityInfo != null) {
3592
3593                            if (!isSystemApp(pm, info.activityInfo.packageName, primaryUser.id)) {
3594                                throw new IllegalArgumentException(
3595                                        "Only system apps can be enabled this way.");
3596                            }
3597
3598
3599                            numberOfAppsInstalled++;
3600                            pm.installExistingPackageAsUser(info.activityInfo.packageName, userId);
3601                        }
3602                    }
3603                }
3604                return numberOfAppsInstalled;
3605            } catch (RemoteException e) {
3606                // shouldn't happen
3607                Slog.wtf(LOG_TAG, "Failed to resolve intent for: " + intent);
3608                return 0;
3609            } finally {
3610                restoreCallingIdentity(id);
3611            }
3612        }
3613    }
3614
3615    private boolean isSystemApp(IPackageManager pm, String packageName, int userId)
3616            throws RemoteException {
3617        ApplicationInfo appInfo = pm.getApplicationInfo(packageName, 0, userId);
3618        return (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0;
3619    }
3620
3621    @Override
3622    public void setAccountManagementDisabled(ComponentName who, String accountType,
3623            boolean disabled) {
3624        if (!mHasFeature) {
3625            return;
3626        }
3627        synchronized (this) {
3628            if (who == null) {
3629                throw new NullPointerException("ComponentName is null");
3630            }
3631            ActiveAdmin ap = getActiveAdminForCallerLocked(who,
3632                    DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3633            if (disabled) {
3634                ap.accountTypesWithManagementDisabled.add(accountType);
3635            } else {
3636                ap.accountTypesWithManagementDisabled.remove(accountType);
3637            }
3638            saveSettingsLocked(UserHandle.getCallingUserId());
3639        }
3640    }
3641
3642    @Override
3643    public String[] getAccountTypesWithManagementDisabled() {
3644        if (!mHasFeature) {
3645            return null;
3646        }
3647        synchronized (this) {
3648            DevicePolicyData policy = getUserData(UserHandle.getCallingUserId());
3649            final int N = policy.mAdminList.size();
3650            HashSet<String> resultSet = new HashSet<String>();
3651            for (int i = 0; i < N; i++) {
3652                ActiveAdmin admin = policy.mAdminList.get(i);
3653                resultSet.addAll(admin.accountTypesWithManagementDisabled);
3654            }
3655            return resultSet.toArray(new String[resultSet.size()]);
3656        }
3657    }
3658
3659    /**
3660     * Sets which componets may enter lock task mode.
3661     *
3662     * This function can only be called by the device owner or the profile owner.
3663     * @param components The list of components allowed to enter lock task mode.
3664     */
3665    public void setLockTaskComponents(ComponentName[] components) throws SecurityException {
3666        // Get the package names of the caller.
3667        int uid = Binder.getCallingUid();
3668        String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
3669
3670        // Check whether any of the package name is the device owner or the profile owner.
3671        for (int i=0; i<packageNames.length; i++) {
3672            String packageName = packageNames[i];
3673            int userHandle = UserHandle.getUserId(uid);
3674            String profileOwnerPackage = getProfileOwner(userHandle);
3675            if (isDeviceOwner(packageName) ||
3676                (profileOwnerPackage != null && profileOwnerPackage.equals(packageName))) {
3677
3678                // If a package name is the device owner or the profile owner,
3679                // we update the component list.
3680                DevicePolicyData policy = getUserData(userHandle);
3681                policy.mLockTaskComponents.clear();
3682                if (components != null) {
3683                    for (int j=0; j<components.length; j++) {
3684                        ComponentName component = components[j];
3685                        policy.mLockTaskComponents.add(component);
3686                    }
3687                }
3688
3689                // Store the settings persistently.
3690                saveSettingsLocked(userHandle);
3691                return;
3692            }
3693        }
3694        throw new SecurityException();
3695    }
3696
3697    /**
3698     * This function returns the list of components allowed to start the task lock mode.
3699     */
3700    public ComponentName[] getLockTaskComponents() {
3701        int userHandle = UserHandle.USER_OWNER;
3702        DevicePolicyData policy = getUserData(userHandle);
3703        ComponentName[] tempArray = policy.mLockTaskComponents.toArray(new ComponentName[0]);
3704        return tempArray;
3705    }
3706
3707    /**
3708     * This function lets the caller know whether the given component is allowed to start the
3709     * lock task mode.
3710     * @param component The component to check
3711     */
3712    public boolean isLockTaskPermitted(ComponentName component) {
3713        // Get current user's devicepolicy
3714        int uid = Binder.getCallingUid();
3715        int userHandle = UserHandle.getUserId(uid);
3716        DevicePolicyData policy = getUserData(userHandle);
3717        for (int i=0; i<policy.mLockTaskComponents.size(); i++) {
3718            ComponentName lockTaskComponent = policy.mLockTaskComponents.get(i);
3719
3720            // If the given component equals one of the component stored our device-owner-set
3721            // list, we allow this component to start the lock task mode.
3722            if (lockTaskComponent.getPackageName().equals(component.getPackageName())) {
3723                return true;
3724            }
3725        }
3726        return false;
3727    }
3728
3729    @Override
3730    public void setGlobalSetting(ComponentName who, String setting, String value) {
3731        final ContentResolver contentResolver = mContext.getContentResolver();
3732
3733        synchronized (this) {
3734            if (who == null) {
3735                throw new NullPointerException("ComponentName is null");
3736            }
3737            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER);
3738
3739            long id = Binder.clearCallingIdentity();
3740            try {
3741                Settings.Global.putString(contentResolver, setting, value);
3742            } finally {
3743                restoreCallingIdentity(id);
3744            }
3745        }
3746    }
3747
3748    @Override
3749    public void setSecureSetting(ComponentName who, String setting, String value) {
3750        int callingUserId = UserHandle.getCallingUserId();
3751        final ContentResolver contentResolver = mContext.getContentResolver();
3752
3753        synchronized (this) {
3754            if (who == null) {
3755                throw new NullPointerException("ComponentName is null");
3756            }
3757            getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER);
3758
3759            long id = Binder.clearCallingIdentity();
3760            try {
3761                Settings.Secure.putStringForUser(contentResolver, setting, value, callingUserId);
3762            } finally {
3763                restoreCallingIdentity(id);
3764            }
3765        }
3766    }
3767}
3768