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