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