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