DevicePolicyManagerService.java revision 21f1bd17b2dfe361acbb28453b3f3b1a110932fa
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.common.FastXmlSerializer; 20import com.android.common.XmlUtils; 21import com.android.internal.content.PackageMonitor; 22import com.android.internal.widget.LockPatternUtils; 23 24import org.xmlpull.v1.XmlPullParser; 25import org.xmlpull.v1.XmlPullParserException; 26import org.xmlpull.v1.XmlSerializer; 27 28import android.app.Activity; 29import android.app.DeviceAdminReceiver; 30import android.app.DeviceAdminInfo; 31import android.app.DevicePolicyManager; 32import android.app.IDevicePolicyManager; 33import android.content.BroadcastReceiver; 34import android.content.ComponentName; 35import android.content.Context; 36import android.content.Intent; 37import android.content.pm.PackageManager; 38import android.content.pm.ResolveInfo; 39import android.content.pm.PackageManager.NameNotFoundException; 40import android.os.Binder; 41import android.os.IBinder; 42import android.os.IPowerManager; 43import android.os.RecoverySystem; 44import android.os.RemoteCallback; 45import android.os.RemoteException; 46import android.os.ServiceManager; 47import android.os.SystemClock; 48import android.util.Log; 49import android.util.Xml; 50import android.view.WindowManagerPolicy; 51 52import java.io.File; 53import java.io.FileInputStream; 54import java.io.FileOutputStream; 55import java.io.IOException; 56import java.util.ArrayList; 57import java.util.HashMap; 58import java.util.List; 59 60/** 61 * Implementation of the device policy APIs. 62 */ 63public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { 64 static final String TAG = "DevicePolicyManagerService"; 65 66 final Context mContext; 67 final MyPackageMonitor mMonitor; 68 69 IPowerManager mIPowerManager; 70 71 int mActivePasswordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 72 int mActivePasswordLength = 0; 73 int mFailedPasswordAttempts = 0; 74 75 final HashMap<ComponentName, ActiveAdmin> mAdminMap 76 = new HashMap<ComponentName, ActiveAdmin>(); 77 final ArrayList<ActiveAdmin> mAdminList 78 = new ArrayList<ActiveAdmin>(); 79 80 static class ActiveAdmin { 81 final DeviceAdminInfo info; 82 83 int passwordQuality = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 84 int minimumPasswordLength = 0; 85 long maximumTimeToUnlock = 0; 86 int maximumFailedPasswordsForWipe = 0; 87 88 ActiveAdmin(DeviceAdminInfo _info) { 89 info = _info; 90 } 91 92 int getUid() { return info.getActivityInfo().applicationInfo.uid; } 93 94 void writeToXml(XmlSerializer out) 95 throws IllegalArgumentException, IllegalStateException, IOException { 96 out.startTag(null, "policies"); 97 info.writePoliciesToXml(out); 98 out.endTag(null, "policies"); 99 if (passwordQuality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 100 out.startTag(null, "password-quality"); 101 out.attribute(null, "value", Integer.toString(passwordQuality)); 102 out.endTag(null, "password-quality"); 103 if (minimumPasswordLength > 0) { 104 out.startTag(null, "min-password-length"); 105 out.attribute(null, "value", Integer.toString(minimumPasswordLength)); 106 out.endTag(null, "mn-password-length"); 107 } 108 } 109 if (maximumTimeToUnlock != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 110 out.startTag(null, "max-time-to-unlock"); 111 out.attribute(null, "value", Long.toString(maximumTimeToUnlock)); 112 out.endTag(null, "max-time-to-unlock"); 113 } 114 if (maximumFailedPasswordsForWipe != 0) { 115 out.startTag(null, "max-failed-password-wipe"); 116 out.attribute(null, "value", Integer.toString(maximumFailedPasswordsForWipe)); 117 out.endTag(null, "max-failed-password-wipe"); 118 } 119 } 120 121 void readFromXml(XmlPullParser parser) 122 throws XmlPullParserException, IOException { 123 int outerDepth = parser.getDepth(); 124 int type; 125 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 126 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 127 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 128 continue; 129 } 130 String tag = parser.getName(); 131 if ("policies".equals(tag)) { 132 info.readPoliciesFromXml(parser); 133 } else if ("password-quality".equals(tag)) { 134 passwordQuality = Integer.parseInt( 135 parser.getAttributeValue(null, "value")); 136 } else if ("min-password-length".equals(tag)) { 137 minimumPasswordLength = Integer.parseInt( 138 parser.getAttributeValue(null, "value")); 139 } else if ("max-time-to-unlock".equals(tag)) { 140 maximumTimeToUnlock = Long.parseLong( 141 parser.getAttributeValue(null, "value")); 142 } else if ("max-failed-password-wipe".equals(tag)) { 143 maximumFailedPasswordsForWipe = Integer.parseInt( 144 parser.getAttributeValue(null, "value")); 145 } else { 146 Log.w(TAG, "Unknown admin tag: " + tag); 147 } 148 XmlUtils.skipCurrentTag(parser); 149 } 150 } 151 } 152 153 class MyPackageMonitor extends PackageMonitor { 154 public void onSomePackagesChanged() { 155 synchronized (DevicePolicyManagerService.this) { 156 for (int i=mAdminList.size()-1; i>=0; i--) { 157 ActiveAdmin aa = mAdminList.get(i); 158 int change = isPackageDisappearing(aa.info.getPackageName()); 159 if (change == PACKAGE_PERMANENT_CHANGE 160 || change == PACKAGE_TEMPORARY_CHANGE) { 161 Log.w(TAG, "Admin unexpectedly uninstalled: " 162 + aa.info.getComponent()); 163 mAdminList.remove(i); 164 } else if (isPackageModified(aa.info.getPackageName())) { 165 try { 166 mContext.getPackageManager().getReceiverInfo( 167 aa.info.getComponent(), 0); 168 } catch (NameNotFoundException e) { 169 Log.w(TAG, "Admin package change removed component: " 170 + aa.info.getComponent()); 171 mAdminList.remove(i); 172 } 173 } 174 } 175 } 176 } 177 } 178 179 /** 180 * Instantiates the service. 181 */ 182 public DevicePolicyManagerService(Context context) { 183 mContext = context; 184 mMonitor = new MyPackageMonitor(); 185 mMonitor.register(context, true); 186 } 187 188 private IPowerManager getIPowerManager() { 189 if (mIPowerManager == null) { 190 IBinder b = ServiceManager.getService(Context.POWER_SERVICE); 191 mIPowerManager = IPowerManager.Stub.asInterface(b); 192 } 193 return mIPowerManager; 194 } 195 196 ActiveAdmin getActiveAdminUncheckedLocked(ComponentName who) { 197 ActiveAdmin admin = mAdminMap.get(who); 198 if (admin != null 199 && who.getPackageName().equals(admin.info.getActivityInfo().packageName) 200 && who.getClassName().equals(admin.info.getActivityInfo().name)) { 201 return admin; 202 } 203 return null; 204 } 205 206 ActiveAdmin getActiveAdminForCallerLocked(ComponentName who, int reqPolicy) 207 throws SecurityException { 208 final int callingUid = Binder.getCallingUid(); 209 if (who != null) { 210 ActiveAdmin admin = mAdminMap.get(who); 211 if (admin == null) { 212 throw new SecurityException("No active admin " + who); 213 } 214 if (admin.getUid() != callingUid) { 215 throw new SecurityException("Admin " + who + " is not owned by uid " 216 + Binder.getCallingUid()); 217 } 218 if (!admin.info.usesPolicy(reqPolicy)) { 219 throw new SecurityException("Admin " + admin.info.getComponent() 220 + " did not specify uses-policy for: " 221 + admin.info.getTagForPolicy(reqPolicy)); 222 } 223 return admin; 224 } else { 225 final int N = mAdminList.size(); 226 for (int i=0; i<N; i++) { 227 ActiveAdmin admin = mAdminList.get(i); 228 if (admin.getUid() == callingUid && admin.info.usesPolicy(reqPolicy)) { 229 return admin; 230 } 231 } 232 throw new SecurityException("No active admin owned by uid " 233 + Binder.getCallingUid() + " for policy #" + reqPolicy); 234 } 235 } 236 237 void sendAdminCommandLocked(ActiveAdmin admin, String action) { 238 Intent intent = new Intent(action); 239 intent.setComponent(admin.info.getComponent()); 240 mContext.sendBroadcast(intent); 241 } 242 243 void sendAdminCommandLocked(String action, int reqPolicy) { 244 final int N = mAdminList.size(); 245 if (N > 0) { 246 for (int i=0; i<N; i++) { 247 ActiveAdmin admin = mAdminList.get(i); 248 if (admin.info.usesPolicy(reqPolicy)) { 249 sendAdminCommandLocked(admin, action); 250 } 251 } 252 } 253 } 254 255 void removeActiveAdminLocked(ComponentName adminReceiver) { 256 ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver); 257 if (admin != null) { 258 sendAdminCommandLocked(admin, 259 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED); 260 // XXX need to wait for it to complete. 261 mAdminList.remove(admin); 262 mAdminMap.remove(adminReceiver); 263 } 264 } 265 266 public DeviceAdminInfo findAdmin(ComponentName adminName) { 267 Intent resolveIntent = new Intent(); 268 resolveIntent.setComponent(adminName); 269 List<ResolveInfo> infos = mContext.getPackageManager().queryBroadcastReceivers( 270 resolveIntent, PackageManager.GET_META_DATA); 271 if (infos == null || infos.size() <= 0) { 272 throw new IllegalArgumentException("Unknown admin: " + adminName); 273 } 274 275 try { 276 return new DeviceAdminInfo(mContext, infos.get(0)); 277 } catch (XmlPullParserException e) { 278 Log.w(TAG, "Bad device admin requested: " + adminName, e); 279 return null; 280 } catch (IOException e) { 281 Log.w(TAG, "Bad device admin requested: " + adminName, e); 282 return null; 283 } 284 } 285 286 private static JournaledFile makeJournaledFile() { 287 final String base = "/data/system/device_policies.xml"; 288 return new JournaledFile(new File(base), new File(base + ".tmp")); 289 } 290 291 private void saveSettingsLocked() { 292 JournaledFile journal = makeJournaledFile(); 293 FileOutputStream stream = null; 294 try { 295 stream = new FileOutputStream(journal.chooseForWrite(), false); 296 XmlSerializer out = new FastXmlSerializer(); 297 out.setOutput(stream, "utf-8"); 298 out.startDocument(null, true); 299 300 out.startTag(null, "policies"); 301 302 final int N = mAdminList.size(); 303 for (int i=0; i<N; i++) { 304 ActiveAdmin ap = mAdminList.get(i); 305 if (ap != null) { 306 out.startTag(null, "admin"); 307 out.attribute(null, "name", ap.info.getComponent().flattenToString()); 308 ap.writeToXml(out); 309 out.endTag(null, "admin"); 310 } 311 } 312 313 out.endTag(null, "policies"); 314 315 if (mFailedPasswordAttempts != 0) { 316 out.startTag(null, "failed-password-attempts"); 317 out.attribute(null, "value", Integer.toString(mFailedPasswordAttempts)); 318 out.endTag(null, "failed-password-attempts"); 319 } 320 321 out.endDocument(); 322 stream.close(); 323 journal.commit(); 324 } catch (IOException e) { 325 try { 326 if (stream != null) { 327 stream.close(); 328 } 329 } catch (IOException ex) { 330 // Ignore 331 } 332 journal.rollback(); 333 } 334 } 335 336 private void loadSettingsLocked() { 337 JournaledFile journal = makeJournaledFile(); 338 FileInputStream stream = null; 339 File file = journal.chooseForRead(); 340 try { 341 stream = new FileInputStream(file); 342 XmlPullParser parser = Xml.newPullParser(); 343 parser.setInput(stream, null); 344 345 int type; 346 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 347 && type != XmlPullParser.START_TAG) { 348 } 349 String tag = parser.getName(); 350 if (!"policies".equals(tag)) { 351 throw new XmlPullParserException( 352 "Settings do not start with policies tag: found " + tag); 353 } 354 type = parser.next(); 355 int outerDepth = parser.getDepth(); 356 while ((type=parser.next()) != XmlPullParser.END_DOCUMENT 357 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { 358 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { 359 continue; 360 } 361 tag = parser.getName(); 362 if ("admin".equals(tag)) { 363 String name = parser.getAttributeValue(null, "name"); 364 try { 365 DeviceAdminInfo dai = findAdmin( 366 ComponentName.unflattenFromString(name)); 367 if (dai != null) { 368 ActiveAdmin ap = new ActiveAdmin(dai); 369 ap.readFromXml(parser); 370 mAdminMap.put(ap.info.getComponent(), ap); 371 mAdminList.add(ap); 372 } 373 } catch (RuntimeException e) { 374 Log.w(TAG, "Failed loading admin " + name, e); 375 } 376 } else if ("failed-password-attempts".equals(tag)) { 377 mFailedPasswordAttempts = Integer.parseInt( 378 parser.getAttributeValue(null, "value")); 379 XmlUtils.skipCurrentTag(parser); 380 } else { 381 Log.w(TAG, "Unknown tag: " + tag); 382 XmlUtils.skipCurrentTag(parser); 383 } 384 } 385 } catch (NullPointerException e) { 386 Log.w(TAG, "failed parsing " + file + " " + e); 387 } catch (NumberFormatException e) { 388 Log.w(TAG, "failed parsing " + file + " " + e); 389 } catch (XmlPullParserException e) { 390 Log.w(TAG, "failed parsing " + file + " " + e); 391 } catch (IOException e) { 392 Log.w(TAG, "failed parsing " + file + " " + e); 393 } catch (IndexOutOfBoundsException e) { 394 Log.w(TAG, "failed parsing " + file + " " + e); 395 } 396 try { 397 if (stream != null) { 398 stream.close(); 399 } 400 } catch (IOException e) { 401 // Ignore 402 } 403 404 long timeMs = getMaximumTimeToLock(null); 405 if (timeMs <= 0) { 406 timeMs = Integer.MAX_VALUE; 407 } 408 try { 409 getIPowerManager().setMaximumScreenOffTimeount((int)timeMs); 410 } catch (RemoteException e) { 411 Log.w(TAG, "Failure talking with power manager", e); 412 } 413 } 414 415 public void systemReady() { 416 synchronized (this) { 417 loadSettingsLocked(); 418 } 419 } 420 421 public void setActiveAdmin(ComponentName adminReceiver) { 422 mContext.enforceCallingOrSelfPermission( 423 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 424 425 DeviceAdminInfo info = findAdmin(adminReceiver); 426 if (info == null) { 427 throw new IllegalArgumentException("Bad admin: " + adminReceiver); 428 } 429 synchronized (this) { 430 long ident = Binder.clearCallingIdentity(); 431 try { 432 if (getActiveAdminUncheckedLocked(adminReceiver) != null) { 433 throw new IllegalArgumentException("Admin is already added"); 434 } 435 ActiveAdmin admin = new ActiveAdmin(info); 436 mAdminMap.put(adminReceiver, admin); 437 mAdminList.add(admin); 438 saveSettingsLocked(); 439 sendAdminCommandLocked(admin, 440 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED); 441 } finally { 442 Binder.restoreCallingIdentity(ident); 443 } 444 } 445 } 446 447 public boolean isAdminActive(ComponentName adminReceiver) { 448 synchronized (this) { 449 return getActiveAdminUncheckedLocked(adminReceiver) != null; 450 } 451 } 452 453 public List<ComponentName> getActiveAdmins() { 454 synchronized (this) { 455 final int N = mAdminList.size(); 456 if (N <= 0) { 457 return null; 458 } 459 ArrayList<ComponentName> res = new ArrayList<ComponentName>(N); 460 for (int i=0; i<N; i++) { 461 res.add(mAdminList.get(i).info.getComponent()); 462 } 463 return res; 464 } 465 } 466 467 public boolean packageHasActiveAdmins(String packageName) { 468 synchronized (this) { 469 final int N = mAdminList.size(); 470 for (int i=0; i<N; i++) { 471 if (mAdminList.get(i).info.getPackageName().equals(packageName)) { 472 return true; 473 } 474 } 475 return false; 476 } 477 } 478 479 public void removeActiveAdmin(ComponentName adminReceiver) { 480 synchronized (this) { 481 ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver); 482 if (admin == null) { 483 return; 484 } 485 if (admin.getUid() != Binder.getCallingUid()) { 486 mContext.enforceCallingOrSelfPermission( 487 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 488 } 489 long ident = Binder.clearCallingIdentity(); 490 try { 491 removeActiveAdminLocked(adminReceiver); 492 } finally { 493 Binder.restoreCallingIdentity(ident); 494 } 495 } 496 } 497 498 public void setPasswordQuality(ComponentName who, int mode) { 499 synchronized (this) { 500 if (who == null) { 501 throw new NullPointerException("ComponentName is null"); 502 } 503 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 504 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 505 if (ap.passwordQuality != mode) { 506 ap.passwordQuality = mode; 507 saveSettingsLocked(); 508 } 509 } 510 } 511 512 public int getPasswordQuality(ComponentName who) { 513 synchronized (this) { 514 int mode = DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 515 516 if (who != null) { 517 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 518 return admin != null ? admin.passwordQuality : mode; 519 } 520 521 final int N = mAdminList.size(); 522 for (int i=0; i<N; i++) { 523 ActiveAdmin admin = mAdminList.get(i); 524 if (mode < admin.passwordQuality) { 525 mode = admin.passwordQuality; 526 } 527 } 528 return mode; 529 } 530 } 531 532 public void setPasswordMinimumLength(ComponentName who, int length) { 533 synchronized (this) { 534 if (who == null) { 535 throw new NullPointerException("ComponentName is null"); 536 } 537 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 538 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 539 if (ap.minimumPasswordLength != length) { 540 ap.minimumPasswordLength = length; 541 saveSettingsLocked(); 542 } 543 } 544 } 545 546 public int getPasswordMinimumLength(ComponentName who) { 547 synchronized (this) { 548 int length = 0; 549 550 if (who != null) { 551 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 552 return admin != null ? admin.minimumPasswordLength : length; 553 } 554 555 final int N = mAdminList.size(); 556 for (int i=0; i<N; i++) { 557 ActiveAdmin admin = mAdminList.get(i); 558 if (length < admin.minimumPasswordLength) { 559 length = admin.minimumPasswordLength; 560 } 561 } 562 return length; 563 } 564 } 565 566 public boolean isActivePasswordSufficient() { 567 synchronized (this) { 568 // This API can only be called by an active device admin, 569 // so try to retrieve it to check that the caller is one. 570 getActiveAdminForCallerLocked(null, 571 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 572 return mActivePasswordQuality >= getPasswordQuality(null) 573 && mActivePasswordLength >= getPasswordMinimumLength(null); 574 } 575 } 576 577 public int getCurrentFailedPasswordAttempts() { 578 synchronized (this) { 579 // This API can only be called by an active device admin, 580 // so try to retrieve it to check that the caller is one. 581 getActiveAdminForCallerLocked(null, 582 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 583 return mFailedPasswordAttempts; 584 } 585 } 586 587 public void setMaximumFailedPasswordsForWipe(ComponentName who, int num) { 588 synchronized (this) { 589 // This API can only be called by an active device admin, 590 // so try to retrieve it to check that the caller is one. 591 getActiveAdminForCallerLocked(who, 592 DeviceAdminInfo.USES_POLICY_WIPE_DATA); 593 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 594 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 595 if (ap.maximumFailedPasswordsForWipe != num) { 596 ap.maximumFailedPasswordsForWipe = num; 597 saveSettingsLocked(); 598 } 599 } 600 } 601 602 public int getMaximumFailedPasswordsForWipe(ComponentName who) { 603 synchronized (this) { 604 int count = 0; 605 606 if (who != null) { 607 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 608 return admin != null ? admin.maximumFailedPasswordsForWipe : count; 609 } 610 611 final int N = mAdminList.size(); 612 for (int i=0; i<N; i++) { 613 ActiveAdmin admin = mAdminList.get(i); 614 if (count == 0) { 615 count = admin.maximumFailedPasswordsForWipe; 616 } else if (admin.maximumFailedPasswordsForWipe != 0 617 && count > admin.maximumFailedPasswordsForWipe) { 618 count = admin.maximumFailedPasswordsForWipe; 619 } 620 } 621 return count; 622 } 623 } 624 625 public boolean resetPassword(String password) { 626 int quality; 627 synchronized (this) { 628 // This API can only be called by an active device admin, 629 // so try to retrieve it to check that the caller is one. 630 getActiveAdminForCallerLocked(null, 631 DeviceAdminInfo.USES_POLICY_RESET_PASSWORD); 632 quality = getPasswordQuality(null); 633 if (quality != DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 634 int adjQuality = LockPatternUtils.adjustPasswordMode(password, quality); 635 if (adjQuality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 636 Log.w(TAG, "resetPassword: password does not meet quality " + quality); 637 return false; 638 } 639 quality = adjQuality; 640 } 641 int length = getPasswordMinimumLength(null); 642 if (password.length() < length) { 643 Log.w(TAG, "resetPassword: password does not meet length " + length); 644 return false; 645 } 646 } 647 648 // Don't do this with the lock held, because it is going to call 649 // back in to the service. 650 long ident = Binder.clearCallingIdentity(); 651 try { 652 LockPatternUtils utils = new LockPatternUtils(mContext); 653 utils.saveLockPassword(password, quality); 654 } finally { 655 Binder.restoreCallingIdentity(ident); 656 } 657 658 return true; 659 } 660 661 public void setMaximumTimeToLock(ComponentName who, long timeMs) { 662 synchronized (this) { 663 if (who == null) { 664 throw new NullPointerException("ComponentName is null"); 665 } 666 ActiveAdmin ap = getActiveAdminForCallerLocked(who, 667 DeviceAdminInfo.USES_POLICY_FORCE_LOCK); 668 if (ap.maximumTimeToUnlock != timeMs) { 669 ap.maximumTimeToUnlock = timeMs; 670 671 long ident = Binder.clearCallingIdentity(); 672 try { 673 saveSettingsLocked(); 674 675 timeMs = getMaximumTimeToLock(null); 676 if (timeMs <= 0) { 677 timeMs = Integer.MAX_VALUE; 678 } 679 680 try { 681 getIPowerManager().setMaximumScreenOffTimeount((int)timeMs); 682 } catch (RemoteException e) { 683 Log.w(TAG, "Failure talking with power manager", e); 684 } 685 } finally { 686 Binder.restoreCallingIdentity(ident); 687 } 688 } 689 } 690 } 691 692 public long getMaximumTimeToLock(ComponentName who) { 693 synchronized (this) { 694 long time = 0; 695 696 if (who != null) { 697 ActiveAdmin admin = getActiveAdminUncheckedLocked(who); 698 return admin != null ? admin.maximumTimeToUnlock : time; 699 } 700 701 final int N = mAdminList.size(); 702 for (int i=0; i<N; i++) { 703 ActiveAdmin admin = mAdminList.get(i); 704 if (time == 0) { 705 time = admin.maximumTimeToUnlock; 706 } else if (admin.maximumTimeToUnlock != 0 707 && time > admin.maximumTimeToUnlock) { 708 time = admin.maximumTimeToUnlock; 709 } 710 } 711 return time; 712 } 713 } 714 715 public void lockNow() { 716 synchronized (this) { 717 // This API can only be called by an active device admin, 718 // so try to retrieve it to check that the caller is one. 719 getActiveAdminForCallerLocked(null, 720 DeviceAdminInfo.USES_POLICY_FORCE_LOCK); 721 long ident = Binder.clearCallingIdentity(); 722 try { 723 mIPowerManager.goToSleepWithReason(SystemClock.uptimeMillis(), 724 WindowManagerPolicy.OFF_BECAUSE_OF_ADMIN); 725 } catch (RemoteException e) { 726 } finally { 727 Binder.restoreCallingIdentity(ident); 728 } 729 } 730 } 731 732 void wipeDataLocked(int flags) { 733 try { 734 RecoverySystem.rebootWipeUserData(mContext); 735 } catch (IOException e) { 736 Log.w(TAG, "Failed requesting data wipe", e); 737 } 738 } 739 740 public void wipeData(int flags) { 741 synchronized (this) { 742 // This API can only be called by an active device admin, 743 // so try to retrieve it to check that the caller is one. 744 getActiveAdminForCallerLocked(null, 745 DeviceAdminInfo.USES_POLICY_WIPE_DATA); 746 long ident = Binder.clearCallingIdentity(); 747 try { 748 wipeDataLocked(flags); 749 } finally { 750 Binder.restoreCallingIdentity(ident); 751 } 752 } 753 } 754 755 public void getRemoveWarning(ComponentName comp, final RemoteCallback result) { 756 mContext.enforceCallingOrSelfPermission( 757 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 758 759 synchronized (this) { 760 ActiveAdmin admin = getActiveAdminUncheckedLocked(comp); 761 if (admin == null) { 762 try { 763 result.sendResult(null); 764 } catch (RemoteException e) { 765 } 766 return; 767 } 768 Intent intent = new Intent(DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLE_REQUESTED); 769 intent.setComponent(admin.info.getComponent()); 770 mContext.sendOrderedBroadcast(intent, null, new BroadcastReceiver() { 771 @Override 772 public void onReceive(Context context, Intent intent) { 773 try { 774 result.sendResult(getResultExtras(false)); 775 } catch (RemoteException e) { 776 } 777 } 778 }, null, Activity.RESULT_OK, null, null); 779 } 780 } 781 782 public void setActivePasswordState(int quality, int length) { 783 mContext.enforceCallingOrSelfPermission( 784 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 785 786 synchronized (this) { 787 if (mActivePasswordQuality != quality || mActivePasswordLength != length 788 || mFailedPasswordAttempts != 0) { 789 long ident = Binder.clearCallingIdentity(); 790 try { 791 mActivePasswordQuality = quality; 792 mActivePasswordLength = length; 793 if (mFailedPasswordAttempts != 0) { 794 mFailedPasswordAttempts = 0; 795 saveSettingsLocked(); 796 } 797 sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED, 798 DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); 799 } finally { 800 Binder.restoreCallingIdentity(ident); 801 } 802 } 803 } 804 } 805 806 public void reportFailedPasswordAttempt() { 807 mContext.enforceCallingOrSelfPermission( 808 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 809 810 synchronized (this) { 811 long ident = Binder.clearCallingIdentity(); 812 try { 813 mFailedPasswordAttempts++; 814 saveSettingsLocked(); 815 int max = getMaximumFailedPasswordsForWipe(null); 816 if (max > 0 && mFailedPasswordAttempts >= max) { 817 wipeDataLocked(0); 818 } 819 sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_FAILED, 820 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 821 } finally { 822 Binder.restoreCallingIdentity(ident); 823 } 824 } 825 } 826 827 public void reportSuccessfulPasswordAttempt() { 828 mContext.enforceCallingOrSelfPermission( 829 android.Manifest.permission.BIND_DEVICE_ADMIN, null); 830 831 synchronized (this) { 832 if (mFailedPasswordAttempts != 0) { 833 long ident = Binder.clearCallingIdentity(); 834 try { 835 mFailedPasswordAttempts = 0; 836 saveSettingsLocked(); 837 sendAdminCommandLocked(DeviceAdminReceiver.ACTION_PASSWORD_SUCCEEDED, 838 DeviceAdminInfo.USES_POLICY_WATCH_LOGIN); 839 } finally { 840 Binder.restoreCallingIdentity(ident); 841 } 842 } 843 } 844 } 845} 846