Merge "Log setting of password complexity."
diff --git a/core/api/current.txt b/core/api/current.txt
index 714f59e..07f8395 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -7344,6 +7344,7 @@
     field public static final int TAG_MEDIA_UNMOUNT = 210014; // 0x3345e
     field public static final int TAG_OS_SHUTDOWN = 210010; // 0x3345a
     field public static final int TAG_OS_STARTUP = 210009; // 0x33459
+    field public static final int TAG_PASSWORD_COMPLEXITY_REQUIRED = 210035; // 0x33473
     field public static final int TAG_PASSWORD_COMPLEXITY_SET = 210017; // 0x33461
     field public static final int TAG_PASSWORD_EXPIRATION_SET = 210016; // 0x33460
     field public static final int TAG_PASSWORD_HISTORY_LENGTH_SET = 210018; // 0x33462
diff --git a/core/java/android/app/admin/SecurityLog.java b/core/java/android/app/admin/SecurityLog.java
index 86f91d7..1cf4567 100644
--- a/core/java/android/app/admin/SecurityLog.java
+++ b/core/java/android/app/admin/SecurityLog.java
@@ -85,7 +85,8 @@
             TAG_CRYPTO_SELF_TEST_COMPLETED,
             TAG_KEY_INTEGRITY_VIOLATION,
             TAG_CERT_VALIDATION_FAILURE,
-            TAG_CAMERA_POLICY_SET
+            TAG_CAMERA_POLICY_SET,
+            TAG_PASSWORD_COMPLEXITY_REQUIRED
     })
     public @interface SecurityLogTag {}
 
@@ -478,6 +479,21 @@
             SecurityLogTags.SECURITY_CAMERA_POLICY_SET;
 
     /**
+     * Indicates that an admin has set a password complexity requirement, using the platform's
+     * pre-defined complexity levels. The log entry contains the following information about the
+     * event, encapsulated in an {@link Object} array and accessible via
+     * {@link SecurityEvent#getData()}:
+     * <li> [0] admin package name ({@code String})
+     * <li> [1] admin user ID ({@code Integer})
+     * <li> [2] target user ID ({@code Integer})
+     * <li> [3] Password complexity ({@code Integer})
+     *
+     * @see DevicePolicyManager#setRequiredPasswordComplexity(int)
+     */
+    public static final int TAG_PASSWORD_COMPLEXITY_REQUIRED =
+            SecurityLogTags.SECURITY_PASSWORD_COMPLEXITY_REQUIRED;
+
+    /**
      * Event severity level indicating that the event corresponds to normal workflow.
      */
     public static final int LEVEL_INFO = 1;
@@ -617,6 +633,7 @@
                 case TAG_USER_RESTRICTION_ADDED:
                 case TAG_USER_RESTRICTION_REMOVED:
                 case TAG_CAMERA_POLICY_SET:
+                case TAG_PASSWORD_COMPLEXITY_REQUIRED:
                     return LEVEL_INFO;
                 case TAG_CERT_AUTHORITY_REMOVED:
                 case TAG_CRYPTO_SELF_TEST_COMPLETED:
diff --git a/core/java/android/app/admin/SecurityLogTags.logtags b/core/java/android/app/admin/SecurityLogTags.logtags
index 100fd4c..db5245c 100644
--- a/core/java/android/app/admin/SecurityLogTags.logtags
+++ b/core/java/android/app/admin/SecurityLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
 
 option java_package android.app.admin
 
@@ -39,3 +39,4 @@
 210032 security_key_integrity_violation         (key_id|3),(uid|1)
 210033 security_cert_validation_failure         (reason|3)
 210034 security_camera_policy_set               (package|3),(admin_user|1),(target_user|1),(disabled|1)
+210035 security_password_complexity_required    (package|3),(admin_user|1),(target_user|1),(complexity|1)
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 38381d2..83b4c82 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -4304,13 +4304,23 @@
                     updatePasswordValidityCheckpointLocked(caller.getUserId(), calledOnParent);
                     updatePasswordQualityCacheForUserGroup(caller.getUserId());
                     saveSettingsLocked(caller.getUserId());
-                    //TODO: Log password complexity change if security logging is enabled.
                 });
             }
+            logPasswordComplexityRequiredIfSecurityLogEnabled(admin.info.getComponent(),
+                    caller.getUserId(), calledOnParent, passwordComplexity);
         }
         //TODO: Log metrics.
     }
 
+    private void logPasswordComplexityRequiredIfSecurityLogEnabled(ComponentName who, int userId,
+            boolean parent, int complexity) {
+        if (SecurityLog.isLoggingEnabled()) {
+            final int affectedUserId = parent ? getProfileParentId(userId) : userId;
+            SecurityLog.writeEvent(SecurityLog.TAG_PASSWORD_COMPLEXITY_REQUIRED,
+                    who.getPackageName(), userId, affectedUserId, complexity);
+        }
+    }
+
     private int getEffectivePasswordComplexityRequirementLocked(@UserIdInt int userHandle) {
         ensureLocked();
         List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked(userHandle);