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