DevicePolicyManagerService.java revision a15dcfaf2bc7cbd13b30db6766afe3bbaa01db97
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.content.PackageMonitor; 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.admin.DeviceAdminInfo; 31import android.app.admin.DeviceAdminReceiver; 32import android.app.admin.DevicePolicyManager; 33import android.app.admin.IDevicePolicyManager; 34import android.content.BroadcastReceiver; 35import android.content.ComponentName; 36import android.content.Context; 37import android.content.Intent; 38import android.content.pm.PackageManager; 39import android.content.pm.ResolveInfo; 40import android.content.pm.PackageManager.NameNotFoundException; 41import android.os.Binder; 42import android.os.IBinder; 43import android.os.IPowerManager; 44import android.os.RecoverySystem; 45import android.os.RemoteCallback; 46import android.os.RemoteException; 47import android.os.ServiceManager; 48import android.os.SystemClock; 49import android.util.Slog; 50import android.util.PrintWriterPrinter; 51import android.util.Printer; 52import android.util.Xml; 53import android.view.WindowManagerPolicy; 54 55import java.io.File; 56import java.io.FileDescriptor; 57import java.io.FileInputStream; 58import java.io.FileOutputStream; 59import java.io.IOException; 60import java.io.PrintWriter; 61import java.util.ArrayList; 62import java.util.HashMap; 63import java.util.List; 64 65/** 66 * Implementation of the device policy APIs. 67 */ 68public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 69 static final String TAG = "DevicePolicyManagerService"; 70 71 final Context mContext; 72 final MyPackageMonitor mMonitor; 73 74 IPowerManager mIPowerManager; 75 76 int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 77 int mActivePasswordLength = 0; 78 int mActivePasswordUpperCase = 0; 79 int mActivePasswordLowerCase = 0; 80 int mActivePasswordLetters = 0; 81 int mActivePasswordNumeric = 0; 82 int mActivePasswordSymbols = 0; 83 int mFailedPasswordAttempts = 0; 84 85 int mPasswordOwner = -1; 86 87 final HashMap<ComponentName, ActiveAdmin> mAdminMap 88 = new HashMap<ComponentName, ActiveAdmin>(); 89 final ArrayList<ActiveAdmin> mAdminList 90 = new ArrayList<ActiveAdmin>(); 91 92 static class ActiveAdmin { 93 final DeviceAdminInfo info; 94 95 int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 96 int minimumPasswordLength = 0; 97 int passwordHistoryLength = 0; 98 int minimumPasswordUpperCase = 0; 99 int minimumPasswordLowerCase = 0; 100 int minimumPasswordLetters = 1; 101 int minimumPasswordNumeric = 1; 102 int minimumPasswordSymbols = 1; 103 long maximumTimeToUnlock = 0; 104 int maximumFailedPasswordsForWipe = 0; 105 106 ActiveAdmin(DeviceAdminInfo _info) { 107 info = _info; 108 } 109 110 int getUid() { return info.getActivityInfo().applicationInfo.uid; } 111 112 void writeToXml(XmlSerializer out) 113 throws IllegalArgumentException, IllegalStateException, IOException { 114 out.startTag(null, "policies"); 115 info.writePoliciesToXml(out); 116 out.endTag(null, "policies"); 117 if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 118 out.startTag(null, "password-quality"); 119 out.attribute(null, "value", Integer.toString(passwordQuality)); 120 out.endTag(null, "password-quality"); 121 if (minimumPasswordLength > 0) { 122 out.startTag(null, "min-password-length"); 123 out.attribute(null, "value", Integer.toString(minimumPasswordLength)); 124 out.endTag(null, "min-password-length"); 125 } 126 if(passwordHistoryLength > 0) { 127 out.startTag(null, "password-history-length"); 128 out.attribute(null, "value", Integer.toString(passwordHistoryLength)); 129 out.endTag(null, "password-history-length"); 130 } 131 if (minimumPasswordUpperCase > 0) { 132 out.startTag(null, "min-password-uppercase"); 133 out.attribute(null, "value", Integer.toString(minimumPasswordUpperCase)); 134 out.endTag(null, "min-password-uppercase"); 135 } 136 if (minimumPasswordLowerCase > 0) { 137 out.startTag(null, "min-password-lowercase"); 138 out.attribute(null, "value", Integer.toString(minimumPasswordLowerCase)); 139 out.endTag(null, "min-password-lowercase"); 140 } 141 if (minimumPasswordLetters > 0) { 142 out.startTag(null, "min-password-letters"); 143 out.attribute(null, "value", Integer.toString(minimumPasswordLetters)); 144 out.endTag(null, "min-password-letters"); 145 } 146 if (minimumPasswordNumeric > 0) { 147 out.startTag(null, "min-password-numeric"); 148 out.attribute(null, "value", Integer.toString(minimumPasswordNumeric)); 149 out.endTag(null, "min-password-numeric"); 150 } 151 if (minimumPasswordSymbols > 0) { 152 out.startTag(null, "min-password-symbols"); 153 out.attribute(null, "value", Integer.toString(minimumPasswordSymbols)); 154 out.endTag(null, "min-password-symbols"); 155 } 156 } 157 if (maximumTimeToUnlock != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 158 out.startTag(null, "max-time-to-unlock"); 159 out.attribute(null, "value", Long.toString(maximumTimeToUnlock)); 160 out.endTag(null, "max-time-to-unlock"); 161 } 162 if (maximumFailedPasswordsForWipe != 0) { 163 out.startTag(null, "max-failed-password-wipe"); 164 out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe)); 165 out.endTag(null, "max-failed-password-wipe"); 166 } 167 } 168 169 void readFromXml(XmlPullParser parser) 170 throws XmlPullParserException, IOException { 171 int outerDepth = parser.getDepth(); 172 int type; 173 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 174 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 175 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 176 continue; 177 } 178 String tag = parser.getName(); 179 if ("policies".equals(tag)) { 180 info.readPoliciesFromXml(parser); 181 } else if ("password-quality".equals(tag)) { 182 passwordQuality = Integer.parseInt( 183 parser.getAttributeValue(null, "value")); 184 } else if ("min-password-length".equals(tag)) { 185 minimumPasswordLength = Integer.parseInt( 186 parser.getAttributeValue(null, "value")); 187 } else if ("password-history-length".equals(tag)) { 188 passwordHistoryLength = Integer.parseInt( 189 parser.getAttributeValue(null, "value")); 190 } else if ("min-password-uppercase".equals(tag)) { 191 minimumPasswordUpperCase = Integer.parseInt( 192 parser.getAttributeValue(null, "value")); 193 } else if ("min-password-lowercase".equals(tag)) { 194 minimumPasswordLowerCase = Integer.parseInt( 195 parser.getAttributeValue(null, "value")); 196 } else if ("min-password-letters".equals(tag)) { 197 minimumPasswordLetters = Integer.parseInt( 198 parser.getAttributeValue(null, "value")); 199 } else if ("min-password-numeric".equals(tag)) { 200 minimumPasswordNumeric = Integer.parseInt( 201 parser.getAttributeValue(null, "value")); 202 } else if ("min-password-symbols".equals(tag)) { 203 minimumPasswordSymbols = Integer.parseInt( 204 parser.getAttributeValue(null, "value")); 205 } else if ("max-time-to-unlock".equals(tag)) { 206 maximumTimeToUnlock = Long.parseLong( 207 parser.getAttributeValue(null, "value")); 208 } else if ("max-failed-password-wipe".equals(tag)) { 209 maximumFailedPasswordsForWipe = Integer.parseInt( 210 parser.getAttributeValue(null, "value")); 211 } else { 212 Slog.w(TAG, "Unknown admin tag: " + tag); 213 } 214 XmlUtils.skipCurrentTag(parser); 215 } 216 } 217 218 void dump(String prefix, PrintWriter pw) { 219 pw.print(prefix); pw.print("uid="); pw.println(getUid()); 220 pw.print(prefix); pw.println("policies:"); 221 ArrayList<DeviceAdminInfo.PolicyInfo> pols = info.getUsedPolicies(); 222 if (pols != null) { 223 for (int i=0; i<pols.size(); i++) { 224 pw.print(prefix); pw.print(" "); pw.println(pols.get(i).tag); 225 } 226 } 227 pw.print(prefix); pw.print("passwordQuality=0x"); 228 pw.println(Integer.toHexString(passwordQuality)); 229 pw.print(prefix); pw.print("minimumPasswordLength="); 230 pw.println(minimumPasswordLength); 231 pw.print(prefix); pw.print("passwordHistoryLength="); 232 pw.println(passwordHistoryLength); 233 pw.print(prefix); pw.print("minimumPasswordUpperCase="); 234 pw.println(minimumPasswordUpperCase); 235 pw.print(prefix); pw.print("minimumPasswordLowerCase="); 236 pw.println(minimumPasswordLowerCase); 237 pw.print(prefix); pw.print("minimumPasswordLetters="); 238 pw.println(minimumPasswordLetters); 239 pw.print(prefix); pw.print("minimumPasswordNumeric="); 240 pw.println(minimumPasswordNumeric); 241 pw.print(prefix); pw.print("minimumPasswordSymbols="); 242 pw.println(minimumPasswordSymbols); 243 pw.print(prefix); pw.print("maximumTimeToUnlock="); 244 pw.println(maximumTimeToUnlock); 245 pw.print(prefix); pw.print("maximumFailedPasswordsForWipe="); 246 pw.println(maximumFailedPasswordsForWipe); 247 } 248 } 249 250 class MyPackageMonitor extends PackageMonitor { 251 public void onSomePackagesChanged() { 252 synchronized (DevicePolicyManagerService.this) { 253 boolean removed = false; 254 for (int i=mAdminList.size()-1; i>=0; i--) { 255 ActiveAdmin aa = mAdminList.get(i); 256 int change = isPackageDisappearing(aa.info.getPackageName()); 257 if (change == PACKAGE_PERMANENT_CHANGE 258 || change == PACKAGE_TEMPORARY_CHANGE) { 259 Slog.w(TAG, "Admin unexpectedly uninstalled: " 260 + aa.info.getComponent()); 261 removed = true; 262 mAdminList.remove(i); 263 } else if (isPackageModified(aa.info.getPackageName())) { 264 try { 265 mContext.getPackageManager().getReceiverInfo( 266 aa.info.getComponent(), 0); 267 } catch (NameNotFoundException e) { 268 Slog.w(TAG, "Admin package change removed component: " 269 + aa.info.getComponent()); 270 removed = true; 271 mAdminList.remove(i); 272 } 273 } 274 } 275 if (removed) { 276 validatePasswordOwnerLocked(); 277 } 278 } 279 } 280 } 281 282 /** 283 * Instantiates the service. 284 */ 285 public DevicePolicyManagerService(Context context) { 286 mContext = context; 287 mMonitor = new MyPackageMonitor(); 288 mMonitor.register(context, true); 289 } 290 291 private IPowerManager getIPowerManager() { 292 if (mIPowerManager == null) { 293 IBinder b = ServiceManager.getService(Context.POWER_SERVICE); 294 mIPowerManager = IPowerManager.Stub.asInterface(b); 295 } 296 return mIPowerManager; 297 } 298 299 ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who) { 300 ActiveAdmin admin = mAdminMap.get(who); 301 if (admin != null 302 && who.getPackageName().equals(admin.info.getActivityInfo().packageName) 303 && who.getClassName().equals(admin.info.getActivityInfo().name)) { 304 return admin; 305 } 306 return null; 307 } 308 309 ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy) 310 throws SecurityException { 311 final int callingUid = Binder.getCallingUid(); 312 if (who != null) { 313 ActiveAdmin admin = mAdminMap.get(who); 314 if (admin == null) { 315 throw new SecurityException("No active admin " + who); 316 } 317 if (admin.getUid() != callingUid) { 318 throw new SecurityException("Admin " + who + " is not owned by uid " 319 + Binder.getCallingUid()); 320 } 321 if (!admin.info.usesPolicy(reqPolicy)) { 322 throw new SecurityException("Admin " + admin.info.getComponent() 323 + " did not specify uses-policy for: " 324 + admin.info.getTagForPolicy(reqPolicy)); 325 } 326 return admin; 327 } else { 328 final int N = mAdminList.size(); 329 for (int i=0; i<N; i++) { 330 ActiveAdmin admin = mAdminList.get(i); 331 if (admin.getUid() == callingUid && admin.info.usesPolicy(reqPolicy)) { 332 return admin; 333 } 334 } 335 throw new SecurityException("No active admin owned by uid " 336 + Binder.getCallingUid() + " for policy #" + reqPolicy); 337 } 338 } 339 340 void sendAdminCommandLocked(ActiveAdmin admin, String action) { 341 Intent intent = new Intent(action); 342 intent.setComponent(admin.info.getComponent()); 343 mContext.sendBroadcast(intent); 344 } 345 346 void sendAdminCommandLocked(String action, int reqPolicy) { 347 final int N = mAdminList.size(); 348 if (N > 0) { 349 for (int i=0; i<N; i++) { 350 ActiveAdmin admin = mAdminList.get(i); 351 if (admin.info.usesPolicy(reqPolicy)) { 352 sendAdminCommandLocked(admin, action); 353 } 354 } 355 } 356 } 357 358 void removeActiveAdminLocked(ComponentName adminReceiver) { 359 ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver); 360 if (admin != null) { 361 sendAdminCommandLocked(admin, 362 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED); 363 // XXX need to wait for it to complete. 364 mAdminList.remove(admin); 365 mAdminMap.remove(adminReceiver); 366 validatePasswordOwnerLocked(); 367 } 368 } 369 370 public DeviceAdminInfo findAdmin(ComponentName adminName) { 371 Intent resolveIntent = new Intent(); 372 resolveIntent.setComponent(adminName); 373 List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceivers( 374 resolveIntent, PackageManager.GET_META_DATA); 375 if (infos == null || infos.size() <= 0) { 376 throw new IllegalArgumentException("Unknown admin: " + adminName); 377 } 378 379 try { 380 return new DeviceAdminInfo(mContext, infos.get(0)); 381 } catch (XmlPullParserException e) { 382 Slog.w(TAG, "Bad device admin requested: " + adminName, e); 383 return null; 384 } catch (IOException e) { 385 Slog.w(TAG, "Bad device admin requested: " + adminName, e); 386 return null; 387 } 388 } 389 390 private static JournaledFile makeJournaledFile() { 391 final String base = "/data/system/device_policies.xml"; 392 return new JournaledFile(new File(base), new File(base + ".tmp")); 393 } 394 395 private void saveSettingsLocked() { 396 JournaledFile journal = makeJournaledFile(); 397 FileOutputStream stream = null; 398 try { 399 stream = new FileOutputStream(journal.chooseForWrite(), false); 400 XmlSerializer out = new FastXmlSerializer(); 401 out.setOutput(stream, "utf-8"); 402 out.startDocument(null, true); 403 404 out.startTag(null, "policies"); 405 406 final int N = mAdminList.size(); 407 for (int i=0; i<N; i++) { 408 ActiveAdmin ap = mAdminList.get(i); 409 if (ap != null) { 410 out.startTag(null, "admin"); 411 out.attribute(null, "name", ap.info.getComponent().flattenToString()); 412 ap.writeToXml(out); 413 out.endTag(null, "admin"); 414 } 415 } 416 417 if (mPasswordOwner >= 0) { 418 out.startTag(null, "password-owner"); 419 out.attribute(null, "value", Integer.toString(mPasswordOwner)); 420 out.endTag(null, "password-owner"); 421 } 422 423 if (mFailedPasswordAttempts != 0) { 424 out.startTag(null, "failed-password-attempts"); 425 out.attribute(null, "value", Integer.toString(mFailedPasswordAttempts)); 426 out.endTag(null, "failed-password-attempts"); 427 } 428 429 if (mActivePasswordQuality != 0 || mActivePasswordLength != 0 430 || mActivePasswordUpperCase != 0 || mActivePasswordLowerCase != 0 431 || mActivePasswordLetters != 0 || mActivePasswordNumeric != 0 432 || mActivePasswordSymbols != 0) { 433 out.startTag(null, "active-password"); 434 out.attribute(null, "quality", Integer.toString(mActivePasswordQuality)); 435 out.attribute(null, "length", Integer.toString(mActivePasswordLength)); 436 out.attribute(null, "uppercase", Integer.toString(mActivePasswordUpperCase)); 437 out.attribute(null, "lowercase", Integer.toString(mActivePasswordLowerCase)); 438 out.attribute(null, "letters", Integer.toString(mActivePasswordLetters)); 439 out.attribute(null, "numeric", Integer 440 .toString(mActivePasswordNumeric)); 441 out.attribute(null, "symbols", Integer.toString(mActivePasswordSymbols)); 442 out.endTag(null, "active-password"); 443 } 444 445 out.endTag(null, "policies"); 446 447 out.endDocument(); 448 stream.close(); 449 journal.commit(); 450 } catch (IOException e) { 451 try { 452 if (stream != null) { 453 stream.close(); 454 } 455 } catch (IOException ex) { 456 // Ignore 457 } 458 journal.rollback(); 459 } 460 } 461 462 private void loadSettingsLocked() { 463 JournaledFile journal = makeJournaledFile(); 464 FileInputStream stream = null; 465 File file = journal.chooseForRead(); 466 try { 467 stream = new FileInputStream(file); 468 XmlPullParser parser = Xml.newPullParser(); 469 parser.setInput(stream, null); 470 471 int type; 472 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 473 && type != XmlPullParser.START_TAG) { 474 } 475 String tag = parser.getName(); 476 if (!"policies".equals(tag)) { 477 throw new XmlPullParserException( 478 "Settings do not start with policies tag: found " + tag); 479 } 480 type = parser.next(); 481 int outerDepth = parser.getDepth(); 482 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 483 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 484 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 485 continue; 486 } 487 tag = parser.getName(); 488 if ("admin".equals(tag)) { 489 String name = parser.getAttributeValue(null, "name"); 490 try { 491 DeviceAdminInfo dai = findAdmin( 492 ComponentName.unflattenFromString(name)); 493 if (dai != null) { 494 ActiveAdmin ap = new ActiveAdmin(dai); 495 ap.readFromXml(parser); 496 mAdminMap.put(ap.info.getComponent(), ap); 497 mAdminList.add(ap); 498 } 499 } catch (RuntimeException e) { 500 Slog.w(TAG, "Failed loading admin " + name, e); 501 } 502 } else if ("failed-password-attempts".equals(tag)) { 503 mFailedPasswordAttempts = Integer.parseInt( 504 parser.getAttributeValue(null, "value")); 505 XmlUtils.skipCurrentTag(parser); 506 } else if ("password-owner".equals(tag)) { 507 mPasswordOwner = Integer.parseInt( 508 parser.getAttributeValue(null, "value")); 509 XmlUtils.skipCurrentTag(parser); 510 } else if ("active-password".equals(tag)) { 511 mActivePasswordQuality = Integer.parseInt( 512 parser.getAttributeValue(null, "quality")); 513 mActivePasswordLength = Integer.parseInt( 514 parser.getAttributeValue(null, "length")); 515 mActivePasswordUpperCase = Integer.parseInt( 516 parser.getAttributeValue(null, "uppercase")); 517 mActivePasswordLowerCase = Integer.parseInt( 518 parser.getAttributeValue(null, "lowercase")); 519 mActivePasswordLetters = Integer.parseInt( 520 parser.getAttributeValue(null, "letters")); 521 mActivePasswordNumeric = Integer.parseInt( 522 parser.getAttributeValue(null, "numeric")); 523 mActivePasswordSymbols = Integer.parseInt( 524 parser.getAttributeValue(null, "symbols")); 525 XmlUtils.skipCurrentTag(parser); 526 } else { 527 Slog.w(TAG, "Unknown tag: " + tag); 528 XmlUtils.skipCurrentTag(parser); 529 } 530 } 531 } catch (NullPointerException e) { 532 Slog.w(TAG, "failed parsing " + file + " " + e); 533 } catch (NumberFormatException e) { 534 Slog.w(TAG, "failed parsing " + file + " " + e); 535 } catch (XmlPullParserException e) { 536 Slog.w(TAG, "failed parsing " + file + " " + e); 537 } catch (IOException e) { 538 Slog.w(TAG, "failed parsing " + file + " " + e); 539 } catch (IndexOutOfBoundsException e) { 540 Slog.w(TAG, "failed parsing " + file + " " + e); 541 } 542 try { 543 if (stream != null) { 544 stream.close(); 545 } 546 } catch (IOException e) { 547 // Ignore 548 } 549 550 // Validate that what we stored for the password quality matches 551 // sufficiently what is currently set. Note that this is only 552 // a sanity check in case the two get out of sync; this should 553 // never normally happen. 554 LockPatternUtils utils = new LockPatternUtils(mContext); 555 if (utils.getActivePasswordQuality() < mActivePasswordQuality) { 556 Slog.w(TAG, "Active password quality 0x" 557 + Integer.toHexString(mActivePasswordQuality) 558 + " does not match actual quality 0x" 559 + Integer.toHexString(utils.getActivePasswordQuality())); 560 mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 561 mActivePasswordLength = 0; 562 mActivePasswordUpperCase = 0; 563 mActivePasswordLowerCase = 0; 564 mActivePasswordLetters = 0; 565 mActivePasswordNumeric = 0; 566 mActivePasswordSymbols = 0; 567 } 568 569 validatePasswordOwnerLocked(); 570 571 long timeMs = getMaximumTimeToLock(null); 572 if (timeMs <= 0) { 573 timeMs = Integer.MAX_VALUE; 574 } 575 try { 576 getIPowerManager().setMaximumScreenOffTimeount((int)timeMs); 577 } catch (RemoteException e) { 578 Slog.w(TAG, "Failure talking with power manager", e); 579 } 580 } 581 582 static void validateQualityConstant(int quality) { 583 switch (quality) { 584 case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED: 585 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 586 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 587 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: 588 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: 589 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: 590 return; 591 } 592 throw new IllegalArgumentException("Invalid quality constant: 0x" 593 + Integer.toHexString(quality)); 594 } 595 596 void validatePasswordOwnerLocked() { 597 if (mPasswordOwner >= 0) { 598 boolean haveOwner = false; 599 for (int i=mAdminList.size()-1; i>=0; i--) { 600 if (mAdminList.get(i).getUid() == mPasswordOwner) { 601 haveOwner = true; 602 break; 603 } 604 } 605 if (!haveOwner) { 606 Slog.w(TAG, "Previous password owner " + mPasswordOwner 607 + " no longer active; disabling"); 608 mPasswordOwner = -1; 609 } 610 } 611 } 612 613 public void systemReady() { 614 synchronized (this) { 615 loadSettingsLocked(); 616 } 617 } 618 619 public void setActiveAdmin(ComponentName adminReceiver) { 620 mContext.enforceCallingOrSelfPermission( 621 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 622 623 DeviceAdminInfo info = findAdmin(adminReceiver); 624 if (info == null) { 625 throw new IllegalArgumentException("Bad admin: " + adminReceiver); 626 } 627 synchronized (this) { 628 long ident = Binder.clearCallingIdentity(); 629 try { 630 if (getActiveAdminUncheckedLocked(adminReceiver) != null) { 631 throw new IllegalArgumentException("Admin is already added"); 632 } 633 ActiveAdmin admin = new ActiveAdmin(info); 634 mAdminMap.put(adminReceiver, admin); 635 mAdminList.add(admin); 636 saveSettingsLocked(); 637 sendAdminCommandLocked(admin, 638 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED); 639 } finally { 640 Binder.restoreCallingIdentity(ident); 641 } 642 } 643 } 644 645 public boolean isAdminActive(ComponentName adminReceiver) { 646 synchronized (this) { 647 return getActiveAdminUncheckedLocked(adminReceiver) != null; 648 } 649 } 650 651 public List<ComponentName> getActiveAdmins() { 652 synchronized (this) { 653 final int N = mAdminList.size(); 654 if (N <= 0) { 655 return null; 656 } 657 ArrayList<ComponentName> res = new ArrayList<ComponentName>(N); 658 for (int i=0; i<N; i++) { 659 res.add(mAdminList.get(i).info.getComponent()); 660 } 661 return res; 662 } 663 } 664 665 public boolean packageHasActiveAdmins(String packageName) { 666 synchronized (this) { 667 final int N = mAdminList.size(); 668 for (int i=0; i<N; i++) { 669 if (mAdminList.get(i).info.getPackageName().equals(packageName)) { 670 return true; 671 } 672 } 673 return false; 674 } 675 } 676 677 public void removeActiveAdmin(ComponentName adminReceiver) { 678 synchronized (this) { 679 ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver); 680 if (admin == null) { 681 return; 682 } 683 if (admin.getUid() != Binder.getCallingUid()) { 684 mContext.enforceCallingOrSelfPermission( 685 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 686 } 687 long ident = Binder.clearCallingIdentity(); 688 try { 689 removeActiveAdminLocked(adminReceiver); 690 } finally { 691 Binder.restoreCallingIdentity(ident); 692 } 693 } 694 } 695 696 public void setPasswordQuality(ComponentName who, int quality) { 697 validateQualityConstant(quality); 698 699 synchronized (this) { 700 if (who == null) { 701 throw new NullPointerException("ComponentName is null"); 702 } 703 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 704 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 705 if (ap.passwordQuality != quality) { 706 ap.passwordQuality = quality; 707 saveSettingsLocked(); 708 } 709 } 710 } 711 712 public int getPasswordQuality(ComponentName who) { 713 synchronized (this) { 714 int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 715 716 if (who != null) { 717 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 718 return admin != null ? admin.passwordQuality : mode; 719 } 720 721 final int N = mAdminList.size(); 722 for (int i=0; i<N; i++) { 723 ActiveAdmin admin = mAdminList.get(i); 724 if (mode < admin.passwordQuality) { 725 mode = admin.passwordQuality; 726 } 727 } 728 return mode; 729 } 730 } 731 732 public void setPasswordMinimumLength(ComponentName who, int length) { 733 synchronized (this) { 734 if (who == null) { 735 throw new NullPointerException("ComponentName is null"); 736 } 737 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 738 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 739 if (ap.minimumPasswordLength != length) { 740 ap.minimumPasswordLength = length; 741 saveSettingsLocked(); 742 } 743 } 744 } 745 746 public int getPasswordMinimumLength(ComponentName who) { 747 synchronized (this) { 748 int length = 0; 749 750 if (who != null) { 751 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 752 return admin != null ? admin.minimumPasswordLength : length; 753 } 754 755 final int N = mAdminList.size(); 756 for (int i=0; i<N; i++) { 757 ActiveAdmin admin = mAdminList.get(i); 758 if (length < admin.minimumPasswordLength) { 759 length = admin.minimumPasswordLength; 760 } 761 } 762 return length; 763 } 764 } 765 766 public void setPasswordHistoryLength(ComponentName who, int length) { 767 synchronized (this) { 768 if (who == null) { 769 throw new NullPointerException("ComponentName is null"); 770 } 771 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 772 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 773 if (ap.passwordHistoryLength != length) { 774 ap.passwordHistoryLength = length; 775 saveSettingsLocked(); 776 } 777 } 778 } 779 780 public int getPasswordHistoryLength(ComponentName who) { 781 synchronized (this) { 782 int length = 0; 783 784 if (who != null) { 785 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 786 return admin != null ? admin.passwordHistoryLength : length; 787 } 788 789 final int N = mAdminList.size(); 790 for (int i = 0; i < N; i++) { 791 ActiveAdmin admin = mAdminList.get(i); 792 if (length < admin.passwordHistoryLength) { 793 length = admin.passwordHistoryLength; 794 } 795 } 796 return length; 797 } 798 } 799 800 public void setPasswordMinimumUpperCase(ComponentName who, int length) { 801 synchronized (this) { 802 if (who == null) { 803 throw new NullPointerException("ComponentName is null"); 804 } 805 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 806 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 807 if (ap.minimumPasswordUpperCase != length) { 808 ap.minimumPasswordUpperCase = length; 809 saveSettingsLocked(); 810 } 811 } 812 } 813 814 public int getPasswordMinimumUpperCase(ComponentName who) { 815 synchronized (this) { 816 int length = 0; 817 818 if (who != null) { 819 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 820 return admin != null ? admin.minimumPasswordUpperCase : length; 821 } 822 823 final int N = mAdminList.size(); 824 for (int i=0; i<N; i++) { 825 ActiveAdmin admin = mAdminList.get(i); 826 if (length < admin.minimumPasswordUpperCase) { 827 length = admin.minimumPasswordUpperCase; 828 } 829 } 830 return length; 831 } 832 } 833 834 public void setPasswordMinimumLowerCase(ComponentName who, int length) { 835 synchronized (this) { 836 if (who == null) { 837 throw new NullPointerException("ComponentName is null"); 838 } 839 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 840 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 841 if (ap.minimumPasswordLowerCase != length) { 842 ap.minimumPasswordLowerCase = length; 843 saveSettingsLocked(); 844 } 845 } 846 } 847 848 public int getPasswordMinimumLowerCase(ComponentName who) { 849 synchronized (this) { 850 int length = 0; 851 852 if (who != null) { 853 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 854 return admin != null ? admin.minimumPasswordLowerCase : length; 855 } 856 857 final int N = mAdminList.size(); 858 for (int i=0; i<N; i++) { 859 ActiveAdmin admin = mAdminList.get(i); 860 if (length < admin.minimumPasswordLowerCase) { 861 length = admin.minimumPasswordLowerCase; 862 } 863 } 864 return length; 865 } 866 } 867 868 public void setPasswordMinimumLetters(ComponentName who, int length) { 869 synchronized (this) { 870 if (who == null) { 871 throw new NullPointerException("ComponentName is null"); 872 } 873 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 874 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 875 if (ap.minimumPasswordLetters != length) { 876 ap.minimumPasswordLetters = length; 877 saveSettingsLocked(); 878 } 879 } 880 } 881 882 public int getPasswordMinimumLetters(ComponentName who) { 883 synchronized (this) { 884 int length = 0; 885 886 if (who != null) { 887 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 888 return admin != null ? admin.minimumPasswordLetters : length; 889 } 890 891 final int N = mAdminList.size(); 892 for (int i=0; i<N; i++) { 893 ActiveAdmin admin = mAdminList.get(i); 894 if (length < admin.minimumPasswordLetters) { 895 length = admin.minimumPasswordLetters; 896 } 897 } 898 return length; 899 } 900 } 901 902 public void setPasswordMinimumNumeric(ComponentName who, int length) { 903 synchronized (this) { 904 if (who == null) { 905 throw new NullPointerException("ComponentName is null"); 906 } 907 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 908 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 909 if (ap.minimumPasswordNumeric != length) { 910 ap.minimumPasswordNumeric = length; 911 saveSettingsLocked(); 912 } 913 } 914 } 915 916 public int getPasswordMinimumNumeric(ComponentName who) { 917 synchronized (this) { 918 int length = 0; 919 920 if (who != null) { 921 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 922 return admin != null ? admin.minimumPasswordNumeric : length; 923 } 924 925 final int N = mAdminList.size(); 926 for (int i = 0; i < N; i++) { 927 ActiveAdmin admin = mAdminList.get(i); 928 if (length < admin.minimumPasswordNumeric) { 929 length = admin.minimumPasswordNumeric; 930 } 931 } 932 return length; 933 } 934 } 935 936 public void setPasswordMinimumSymbols(ComponentName who, int length) { 937 synchronized (this) { 938 if (who == null) { 939 throw new NullPointerException("ComponentName is null"); 940 } 941 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 942 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 943 if (ap.minimumPasswordSymbols != length) { 944 ap.minimumPasswordSymbols = length; 945 saveSettingsLocked(); 946 } 947 } 948 } 949 950 public int getPasswordMinimumSymbols(ComponentName who) { 951 synchronized (this) { 952 int length = 0; 953 954 if (who != null) { 955 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 956 return admin != null ? admin.minimumPasswordSymbols : length; 957 } 958 959 final int N = mAdminList.size(); 960 for (int i=0; i<N; i++) { 961 ActiveAdmin admin = mAdminList.get(i); 962 if (length < admin.minimumPasswordSymbols) { 963 length = admin.minimumPasswordSymbols; 964 } 965 } 966 return length; 967 } 968 } 969 970 public boolean isActivePasswordSufficient() { 971 synchronized (this) { 972 // This API can only be called by an active device admin, 973 // so try to retrieve it to check that the caller is one. 974 getActiveAdminForCallerLocked(null, 975 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 976 if (mActivePasswordQuality < getPasswordQuality(null) 977 || mActivePasswordLength < getPasswordMinimumLength(null)) { 978 return false; 979 } 980 if(mActivePasswordQuality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { 981 return true; 982 } 983 return mActivePasswordUpperCase >= getPasswordMinimumUpperCase(null) 984 && mActivePasswordLowerCase >= getPasswordMinimumLowerCase(null) 985 && mActivePasswordLetters >= getPasswordMinimumLetters(null) 986 && mActivePasswordNumeric >= getPasswordMinimumNumeric(null) 987 && mActivePasswordSymbols >= getPasswordMinimumSymbols(null); 988 } 989 } 990 991 public int getCurrentFailedPasswordAttempts() { 992 synchronized (this) { 993 // This API can only be called by an active device admin, 994 // so try to retrieve it to check that the caller is one. 995 getActiveAdminForCallerLocked(null, 996 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 997 return mFailedPasswordAttempts; 998 } 999 } 1000 1001 public void setMaximumFailedPasswordsForWipe(ComponentName who, int num) { 1002 synchronized (this) { 1003 // This API can only be called by an active device admin, 1004 // so try to retrieve it to check that the caller is one. 1005 getActiveAdminForCallerLocked(who, 1006 DeviceAdminInfo.USES_POLICY_WIPE_DATA); 1007 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1008 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 1009 if (ap.maximumFailedPasswordsForWipe != num) { 1010 ap.maximumFailedPasswordsForWipe = num; 1011 saveSettingsLocked(); 1012 } 1013 } 1014 } 1015 1016 public int getMaximumFailedPasswordsForWipe(ComponentName who) { 1017 synchronized (this) { 1018 int count = 0; 1019 1020 if (who != null) { 1021 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1022 return admin != null ? admin.maximumFailedPasswordsForWipe : count; 1023 } 1024 1025 final int N = mAdminList.size(); 1026 for (int i=0; i<N; i++) { 1027 ActiveAdmin admin = mAdminList.get(i); 1028 if (count == 0) { 1029 count = admin.maximumFailedPasswordsForWipe; 1030 } else if (admin.maximumFailedPasswordsForWipe != 0 1031 && count > admin.maximumFailedPasswordsForWipe) { 1032 count = admin.maximumFailedPasswordsForWipe; 1033 } 1034 } 1035 return count; 1036 } 1037 } 1038 1039 public boolean resetPassword(String password, int flags) { 1040 int quality; 1041 synchronized (this) { 1042 // This API can only be called by an active device admin, 1043 // so try to retrieve it to check that the caller is one. 1044 getActiveAdminForCallerLocked(null, 1045 DeviceAdminInfo.USES_POLICY_RESET_PASSWORD); 1046 quality = getPasswordQuality(null); 1047 if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 1048 int realQuality = LockPatternUtils.computePasswordQuality(password); 1049 if (realQuality < quality 1050 && quality != DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { 1051 Slog.w(TAG, "resetPassword: password quality 0x" 1052 + Integer.toHexString(quality) 1053 + " does not meet required quality 0x" 1054 + Integer.toHexString(quality)); 1055 return false; 1056 } 1057 quality = Math.max(realQuality, quality); 1058 } 1059 int length = getPasswordMinimumLength(null); 1060 if (password.length() < length) { 1061 Slog.w(TAG, "resetPassword: password length " + password.length() 1062 + " does not meet required length " + length); 1063 return false; 1064 } 1065 if (quality == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX) { 1066 int letters = 0; 1067 int uppercase = 0; 1068 int lowercase = 0; 1069 int numbers = 0; 1070 int symbols = 0; 1071 for (int i = 0; i < password.length(); i++) { 1072 char c = password.charAt(i); 1073 if (c >= 'A' && c <= 'Z') { 1074 letters++; 1075 uppercase++; 1076 } else if (c >= 'a' && c <= 'z') { 1077 letters++; 1078 lowercase++; 1079 } else if (c >= '0' && c <= '9') { 1080 numbers++; 1081 } else { 1082 symbols++; 1083 } 1084 } 1085 int neededLetters = getPasswordMinimumLetters(null); 1086 if(letters < neededLetters) { 1087 Slog.w(TAG, "resetPassword: number of letters " + letters 1088 + " does not meet required number of letters " + neededLetters); 1089 return false; 1090 } 1091 int neededNumbers = getPasswordMinimumNumeric(null); 1092 if (numbers < neededNumbers) { 1093 Slog 1094 .w(TAG, "resetPassword: number of numerical digits " + numbers 1095 + " does not meet required number of numerical digits " 1096 + neededNumbers); 1097 return false; 1098 } 1099 int neededLowerCase = getPasswordMinimumLowerCase(null); 1100 if (lowercase < neededLowerCase) { 1101 Slog.w(TAG, "resetPassword: number of lowercase letters " + lowercase 1102 + " does not meet required number of lowercase letters " 1103 + neededLowerCase); 1104 return false; 1105 } 1106 int neededUpperCase = getPasswordMinimumUpperCase(null); 1107 if (uppercase < neededUpperCase) { 1108 Slog.w(TAG, "resetPassword: number of uppercase letters " + uppercase 1109 + " does not meet required number of uppercase letters " 1110 + neededUpperCase); 1111 return false; 1112 } 1113 int neededSymbols = getPasswordMinimumSymbols(null); 1114 if (symbols < neededSymbols) { 1115 Slog.w(TAG, "resetPassword: number of special symbols " + symbols 1116 + " does not meet required number of special symbols " + neededSymbols); 1117 return false; 1118 } 1119 } 1120 1121 LockPatternUtils utils = new LockPatternUtils(mContext); 1122 if(utils.checkPasswordHistory(password)) { 1123 Slog.w(TAG, "resetPassword: password is the same as one of the last " 1124 + getPasswordHistoryLength(null) + " passwords"); 1125 return false; 1126 } 1127 } 1128 1129 int callingUid = Binder.getCallingUid(); 1130 if (mPasswordOwner >= 0 && mPasswordOwner != callingUid) { 1131 Slog.w(TAG, "resetPassword: already set by another uid and not entered by user"); 1132 return false; 1133 } 1134 1135 // Don't do this with the lock held, because it is going to call 1136 // back in to the service. 1137 long ident = Binder.clearCallingIdentity(); 1138 try { 1139 LockPatternUtils utils = new LockPatternUtils(mContext); 1140 utils.saveLockPassword(password, quality); 1141 synchronized (this) { 1142 int newOwner = (flags&DevicePolicyManager.RESET_PASSWORD_REQUIRE_ENTRY) 1143 != 0 ? callingUid : -1; 1144 if (mPasswordOwner != newOwner) { 1145 mPasswordOwner = newOwner; 1146 saveSettingsLocked(); 1147 } 1148 } 1149 } finally { 1150 Binder.restoreCallingIdentity(ident); 1151 } 1152 1153 return true; 1154 } 1155 1156 public void setMaximumTimeToLock(ComponentName who, long timeMs) { 1157 synchronized (this) { 1158 if (who == null) { 1159 throw new NullPointerException("ComponentName is null"); 1160 } 1161 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 1162 DeviceAdminInfo.USES_POLICY_FORCE_LOCK); 1163 if (ap.maximumTimeToUnlock != timeMs) { 1164 ap.maximumTimeToUnlock = timeMs; 1165 1166 long ident = Binder.clearCallingIdentity(); 1167 try { 1168 saveSettingsLocked(); 1169 1170 timeMs = getMaximumTimeToLock(null); 1171 if (timeMs <= 0) { 1172 timeMs = Integer.MAX_VALUE; 1173 } 1174 1175 try { 1176 getIPowerManager().setMaximumScreenOffTimeount((int)timeMs); 1177 } catch (RemoteException e) { 1178 Slog.w(TAG, "Failure talking with power manager", e); 1179 } 1180 } finally { 1181 Binder.restoreCallingIdentity(ident); 1182 } 1183 } 1184 } 1185 } 1186 1187 public long getMaximumTimeToLock(ComponentName who) { 1188 synchronized (this) { 1189 long time = 0; 1190 1191 if (who != null) { 1192 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 1193 return admin != null ? admin.maximumTimeToUnlock : time; 1194 } 1195 1196 final int N = mAdminList.size(); 1197 for (int i=0; i<N; i++) { 1198 ActiveAdmin admin = mAdminList.get(i); 1199 if (time == 0) { 1200 time = admin.maximumTimeToUnlock; 1201 } else if (admin.maximumTimeToUnlock != 0 1202 && time > admin.maximumTimeToUnlock) { 1203 time = admin.maximumTimeToUnlock; 1204 } 1205 } 1206 return time; 1207 } 1208 } 1209 1210 public void lockNow() { 1211 synchronized (this) { 1212 // This API can only be called by an active device admin, 1213 // so try to retrieve it to check that the caller is one. 1214 getActiveAdminForCallerLocked(null, 1215 DeviceAdminInfo.USES_POLICY_FORCE_LOCK); 1216 long ident = Binder.clearCallingIdentity(); 1217 try { 1218 mIPowerManager.goToSleepWithReason(SystemClock.uptimeMillis(), 1219 WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN); 1220 } catch (RemoteException e) { 1221 } finally { 1222 Binder.restoreCallingIdentity(ident); 1223 } 1224 } 1225 } 1226 1227 void wipeDataLocked(int flags) { 1228 try { 1229 RecoverySystem.rebootWipeUserData(mContext); 1230 } catch (IOException e) { 1231 Slog.w(TAG, "Failed requesting data wipe", e); 1232 } 1233 } 1234 1235 public void wipeData(int flags) { 1236 synchronized (this) { 1237 // This API can only be called by an active device admin, 1238 // so try to retrieve it to check that the caller is one. 1239 getActiveAdminForCallerLocked(null, 1240 DeviceAdminInfo.USES_POLICY_WIPE_DATA); 1241 long ident = Binder.clearCallingIdentity(); 1242 try { 1243 wipeDataLocked(flags); 1244 } finally { 1245 Binder.restoreCallingIdentity(ident); 1246 } 1247 } 1248 } 1249 1250 public void getRemoveWarning(ComponentName comp, final RemoteCallback result) { 1251 mContext.enforceCallingOrSelfPermission( 1252 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 1253 1254 synchronized (this) { 1255 ActiveAdmin admin = getActiveAdminUncheckedLocked(comp); 1256 if (admin == null) { 1257 try { 1258 result.sendResult(null); 1259 } catch (RemoteException e) { 1260 } 1261 return; 1262 } 1263 Intent intent = new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED); 1264 intent.setComponent(admin.info.getComponent()); 1265 mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() { 1266 @Override 1267 public void onReceive(Context context, Intent intent) { 1268 try { 1269 result.sendResult(getResultExtras(false)); 1270 } catch (RemoteException e) { 1271 } 1272 } 1273 }, null, Activity.RESULT_OK, null, null); 1274 } 1275 } 1276 1277 public void setActivePasswordState(int quality, int length, int letters, int uppercase, 1278 int lowercase, int numbers, int symbols) { 1279 mContext.enforceCallingOrSelfPermission( 1280 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 1281 1282 validateQualityConstant(quality); 1283 1284 synchronized (this) { 1285 if (mActivePasswordQuality != quality || mActivePasswordLength != length 1286 || mFailedPasswordAttempts != 0 || mActivePasswordLetters != letters 1287 || mActivePasswordUpperCase != uppercase 1288 || mActivePasswordLowerCase != lowercase || mActivePasswordNumeric != numbers 1289 || mActivePasswordSymbols != symbols) { 1290 long ident = Binder.clearCallingIdentity(); 1291 try { 1292 mActivePasswordQuality = quality; 1293 mActivePasswordLength = length; 1294 mActivePasswordLetters = letters; 1295 mActivePasswordLowerCase = lowercase; 1296 mActivePasswordUpperCase = uppercase; 1297 mActivePasswordNumeric = numbers; 1298 mActivePasswordSymbols = symbols; 1299 mFailedPasswordAttempts = 0; 1300 saveSettingsLocked(); 1301 sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED, 1302 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 1303 } finally { 1304 Binder.restoreCallingIdentity(ident); 1305 } 1306 } 1307 } 1308 } 1309 1310 public void reportFailedPasswordAttempt() { 1311 mContext.enforceCallingOrSelfPermission( 1312 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 1313 1314 synchronized (this) { 1315 long ident = Binder.clearCallingIdentity(); 1316 try { 1317 mFailedPasswordAttempts++; 1318 saveSettingsLocked(); 1319 int max = getMaximumFailedPasswordsForWipe(null); 1320 if (max > 0 && mFailedPasswordAttempts >= max) { 1321 wipeDataLocked(0); 1322 } 1323 sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_FAILED, 1324 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 1325 } finally { 1326 Binder.restoreCallingIdentity(ident); 1327 } 1328 } 1329 } 1330 1331 public void reportSuccessfulPasswordAttempt() { 1332 mContext.enforceCallingOrSelfPermission( 1333 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 1334 1335 synchronized (this) { 1336 if (mFailedPasswordAttempts != 0 || mPasswordOwner >= 0) { 1337 long ident = Binder.clearCallingIdentity(); 1338 try { 1339 mFailedPasswordAttempts = 0; 1340 mPasswordOwner = -1; 1341 saveSettingsLocked(); 1342 sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED, 1343 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 1344 } finally { 1345 Binder.restoreCallingIdentity(ident); 1346 } 1347 } 1348 } 1349 } 1350 1351 @Override 1352 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1353 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 1354 != PackageManager.PERMISSION_GRANTED) { 1355 1356 pw.println("Permission Denial: can't dump DevicePolicyManagerService from from pid=" 1357 + Binder.getCallingPid() 1358 + ", uid=" + Binder.getCallingUid()); 1359 return; 1360 } 1361 1362 final Printer p = new PrintWriterPrinter(pw); 1363 1364 synchronized (this) { 1365 p.println("Current Device Policy Manager state:"); 1366 1367 p.println(" Enabled Device Admins:"); 1368 final int N = mAdminList.size(); 1369 for (int i=0; i<N; i++) { 1370 ActiveAdmin ap = mAdminList.get(i); 1371 if (ap != null) { 1372 pw.print(" "); pw.print(ap.info.getComponent().flattenToShortString()); 1373 pw.println(":"); 1374 ap.dump(" ", pw); 1375 } 1376 } 1377 1378 pw.println(" "); 1379 pw.print(" mActivePasswordQuality=0x"); 1380 pw.println(Integer.toHexString(mActivePasswordQuality)); 1381 pw.print(" mActivePasswordLength="); pw.println(mActivePasswordLength); 1382 pw.print(" mActivePasswordUpperCase="); pw.println(mActivePasswordUpperCase); 1383 pw.print(" mActivePasswordLowerCase="); pw.println(mActivePasswordLowerCase); 1384 pw.print(" mActivePasswordLetters="); pw.println(mActivePasswordLetters); 1385 pw.print(" mActivePasswordNumeric="); pw.println(mActivePasswordNumeric); 1386 pw.print(" mActivePasswordSymbols="); pw.println(mActivePasswordSymbols); 1387 pw.print(" mFailedPasswordAttempts="); pw.println(mFailedPasswordAttempts); 1388 pw.print(" mPasswordOwner="); pw.println(mPasswordOwner); 1389 } 1390 } 1391} 1392