summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt1
-rw-r--r--core/java/android/app/admin/DevicePolicyIdentifiers.java8
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java18
-rw-r--r--core/java/android/app/admin/DevicePolicyManagerInternal.java5
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java208
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/Owners.java13
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java8
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java9
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java9
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java10
10 files changed, 239 insertions, 50 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index db7334e2eb16..391867d8e7a5 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -7958,6 +7958,7 @@ package android.app.admin {
field public static final String PERMISSION_GRANT_POLICY = "permissionGrant";
field public static final String PERSISTENT_PREFERRED_ACTIVITY_POLICY = "persistentPreferredActivity";
field public static final String RESET_PASSWORD_TOKEN_POLICY = "resetPasswordToken";
+ field @FlaggedApi("android.app.admin.flags.security_log_v2_enabled") public static final String SECURITY_LOGGING_POLICY = "securityLogging";
field public static final String STATUS_BAR_DISABLED_POLICY = "statusBarDisabled";
field @FlaggedApi("android.app.admin.flags.policy_engine_migration_v2_enabled") public static final String USB_DATA_SIGNALING_POLICY = "usbDataSignaling";
field public static final String USER_CONTROL_DISABLED_PACKAGES_POLICY = "userControlDisabledPackages";
diff --git a/core/java/android/app/admin/DevicePolicyIdentifiers.java b/core/java/android/app/admin/DevicePolicyIdentifiers.java
index d7aafa010e1d..318b2fb7b980 100644
--- a/core/java/android/app/admin/DevicePolicyIdentifiers.java
+++ b/core/java/android/app/admin/DevicePolicyIdentifiers.java
@@ -16,6 +16,8 @@
package android.app.admin;
+import static android.app.admin.flags.Flags.FLAG_SECURITY_LOG_V2_ENABLED;
+
import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.annotation.TestApi;
@@ -45,6 +47,12 @@ public final class DevicePolicyIdentifiers {
public static final String PERMISSION_GRANT_POLICY = "permissionGrant";
/**
+ * String identifier for {@link DevicePolicyManager#setSecurityLoggingEnabled}.
+ */
+ @FlaggedApi(FLAG_SECURITY_LOG_V2_ENABLED)
+ public static final String SECURITY_LOGGING_POLICY = "securityLogging";
+
+ /**
* String identifier for {@link DevicePolicyManager#setLockTaskPackages}.
*/
public static final String LOCK_TASK_POLICY = "lockTask";
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 9d50810425c6..5c6308f209fe 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -13976,6 +13976,24 @@ public class DevicePolicyManager {
* privacy-sensitive events happening outside the managed profile would have been redacted
* already.
*
+ * Starting from {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}, after the security logging
+ * policy has been set, {@link PolicyUpdateReceiver#onPolicySetResult(Context, String,
+ * Bundle, TargetUser, PolicyUpdateResult)} will notify the admin on whether the policy was
+ * successfully set or not. This callback will contain:
+ * <ul>
+ * <li> The policy identifier {@link DevicePolicyIdentifiers#SECURITY_LOGGING_POLICY}
+ * <li> The {@link TargetUser} that this policy relates to
+ * <li> The {@link PolicyUpdateResult}, which will be
+ * {@link PolicyUpdateResult#RESULT_POLICY_SET} if the policy was successfully set or the
+ * reason the policy failed to be set
+ * e.g. {@link PolicyUpdateResult#RESULT_FAILURE_CONFLICTING_ADMIN_POLICY})
+ * </ul>
+ * If there has been a change to the policy,
+ * {@link PolicyUpdateReceiver#onPolicyChanged(Context, String, Bundle, TargetUser,
+ * PolicyUpdateResult)} will notify the admin of this change. This callback will contain the
+ * same parameters as PolicyUpdateReceiver#onPolicySetResult and the {@link PolicyUpdateResult}
+ * will contain the reason why the policy changed.
+ *
* @param admin Which device admin this request is associated with, or {@code null}
* if called by a delegated app.
* @param enabled whether security logging should be enabled or not.
diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java
index 304359bc6105..07ee8de587f8 100644
--- a/core/java/android/app/admin/DevicePolicyManagerInternal.java
+++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java
@@ -333,4 +333,9 @@ public abstract class DevicePolicyManagerInternal {
*/
public abstract List<EnforcingUser> getUserRestrictionSources(String restriction,
@UserIdInt int userId);
+
+ /**
+ * Enforces resolved security logging policy, should only be invoked from device policy engine.
+ */
+ public abstract void enforceSecurityLoggingPolicy(boolean enabled);
}
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 51eee64d12f2..b7a2271d8803 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -237,6 +237,7 @@ import static android.app.admin.flags.Flags.dumpsysPolicyEngineMigrationEnabled;
import static android.app.admin.flags.Flags.headlessDeviceOwnerSingleUserEnabled;
import static android.app.admin.flags.Flags.policyEngineMigrationV2Enabled;
import static android.app.admin.flags.Flags.assistContentUserRestrictionEnabled;
+import static android.app.admin.flags.Flags.securityLogV2Enabled;
import static android.content.Intent.ACTION_MANAGED_PROFILE_AVAILABLE;
import static android.content.Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
@@ -3376,9 +3377,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
applyProfileRestrictionsIfDeviceOwnerLocked();
// TODO: Is this the right place to trigger the migration?
- if (shouldMigrateToDevicePolicyEngine()) {
- migratePoliciesToDevicePolicyEngine();
+ if (shouldMigrateV1ToDevicePolicyEngine()) {
+ migrateV1PoliciesToDevicePolicyEngine();
}
+ migratePoliciesToPolicyEngineLocked();
}
maybeStartSecurityLogMonitorOnActivityManagerReady();
break;
@@ -3392,6 +3394,48 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ @GuardedBy("getLockObject()")
+ private void maybeMigrateSecurityLoggingPolicyLocked() {
+ if (!securityLogV2Enabled() || mOwners.isSecurityLoggingMigrated()) {
+ return;
+ }
+
+ try {
+ migrateSecurityLoggingPolicyInternalLocked();
+ } catch (Exception e) {
+ Slog.e(LOG_TAG, "Failed to properly migrate security logging to policy engine", e);
+ }
+
+ Slog.i(LOG_TAG, "Marking security logging policy migration complete");
+ mOwners.markSecurityLoggingMigrated();
+ }
+
+ @GuardedBy("getLockObject()")
+ private void migrateSecurityLoggingPolicyInternalLocked() {
+ Slog.i(LOG_TAG, "Migrating security logging policy to policy engine");
+ if (!mInjector.securityLogGetLoggingEnabledProperty()) {
+ Slog.i(LOG_TAG, "Security logs not enabled, exiting");
+ return;
+ }
+
+ // Security logging can be enabled either by DO or by COPE PO.
+ final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked();
+ if (admin == null) {
+ Slog.wtf(LOG_TAG, "Security logging is enabled, but no appropriate admin found");
+ return;
+ }
+
+ EnforcingAdmin enforcingAdmin =
+ EnforcingAdmin.createEnterpriseEnforcingAdmin(
+ admin.info.getComponent(),
+ admin.getUserHandle().getIdentifier(),
+ admin);
+ mDevicePolicyEngine.setGlobalPolicy(
+ PolicyDefinition.SECURITY_LOGGING,
+ enforcingAdmin,
+ new BooleanPolicyValue(true));
+ }
+
private void applyManagedSubscriptionsPolicyIfRequired() {
int copeProfileUserId = getOrganizationOwnedProfileUserId();
// This policy is relevant only for COPE devices.
@@ -15721,6 +15765,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return enforcingUsers;
}
+ @Override
+ public void enforceSecurityLoggingPolicy(boolean enabled) {
+ enforceLoggingPolicy(enabled);
+ }
+
private List<EnforcingUser> getEnforcingUsers(Set<EnforcingAdmin> admins) {
List<EnforcingUser> enforcingUsers = new ArrayList();
ComponentName deviceOwner = mOwners.getDeviceOwnerComponent();
@@ -15738,6 +15787,20 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
}
+ private void enforceLoggingPolicy(boolean securityLoggingEnabled) {
+ Slogf.i(LOG_TAG, "Enforcing security logging, securityLoggingEnabled: %b",
+ securityLoggingEnabled);
+ SecurityLog.setLoggingEnabledProperty(securityLoggingEnabled);
+ if (securityLoggingEnabled) {
+ mSecurityLogMonitor.start(getSecurityLoggingEnabledUser());
+ synchronized (getLockObject()) {
+ maybePauseDeviceWideLoggingLocked();
+ }
+ } else {
+ mSecurityLogMonitor.stop();
+ }
+ }
+
private Intent createShowAdminSupportIntent(int userId) {
// This method is called with AMS lock held, so don't take DPMS lock
final Intent intent = new Intent(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS);
@@ -17586,19 +17649,32 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
@Override
- public void setSecurityLoggingEnabled(ComponentName admin, String packageName,
+ public void setSecurityLoggingEnabled(ComponentName who, String packageName,
boolean enabled) {
if (!mHasFeature) {
return;
}
- final CallerIdentity caller = getCallerIdentity(admin, packageName);
+ final CallerIdentity caller = getCallerIdentity(who, packageName);
- synchronized (getLockObject()) {
- if (isPermissionCheckFlagEnabled()) {
- enforcePermission(MANAGE_DEVICE_POLICY_SECURITY_LOGGING, caller.getPackageName(),
- UserHandle.USER_ALL);
+ if (securityLogV2Enabled()) {
+ EnforcingAdmin admin = enforcePermissionAndGetEnforcingAdmin(
+ who,
+ MANAGE_DEVICE_POLICY_SECURITY_LOGGING,
+ caller.getPackageName(),
+ caller.getUserId());
+ if (enabled) {
+ mDevicePolicyEngine.setGlobalPolicy(
+ PolicyDefinition.SECURITY_LOGGING,
+ admin,
+ new BooleanPolicyValue(true));
} else {
- if (admin != null) {
+ mDevicePolicyEngine.removeGlobalPolicy(
+ PolicyDefinition.SECURITY_LOGGING,
+ admin);
+ }
+ } else {
+ synchronized (getLockObject()) {
+ if (who != null) {
Preconditions.checkCallAuthorization(
isProfileOwnerOfOrganizationOwnedDevice(caller)
|| isDefaultDeviceOwner(caller));
@@ -17607,17 +17683,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
Preconditions.checkCallAuthorization(
isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
}
- }
- if (enabled == mInjector.securityLogGetLoggingEnabledProperty()) {
- return;
- }
- mInjector.securityLogSetLoggingEnabledProperty(enabled);
- if (enabled) {
- mSecurityLogMonitor.start(getSecurityLoggingEnabledUser());
- maybePauseDeviceWideLoggingLocked();
- } else {
- mSecurityLogMonitor.stop();
+ if (enabled == mInjector.securityLogGetLoggingEnabledProperty()) {
+ return;
+ }
+ mInjector.securityLogSetLoggingEnabledProperty(enabled);
+ if (enabled) {
+ mSecurityLogMonitor.start(getSecurityLoggingEnabledUser());
+ maybePauseDeviceWideLoggingLocked();
+ } else {
+ mSecurityLogMonitor.stop();
+ }
}
}
DevicePolicyEventLogger
@@ -17633,25 +17709,35 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
return false;
}
- synchronized (getLockObject()) {
- if (!isSystemUid(getCallerIdentity())) {
- final CallerIdentity caller = getCallerIdentity(admin, packageName);
- if (isPermissionCheckFlagEnabled()) {
- enforcePermission(MANAGE_DEVICE_POLICY_SECURITY_LOGGING,
- caller.getPackageName(), UserHandle.USER_ALL);
+ final CallerIdentity caller = getCallerIdentity(admin, packageName);
+ if (isSystemUid(caller)) {
+ // Settings uses this for privacy transparency.
+ // TODO: create a separate @hidden API for settings.
+ return mInjector.securityLogGetLoggingEnabledProperty();
+ }
+
+ if (securityLogV2Enabled()) {
+ final EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
+ admin,
+ MANAGE_DEVICE_POLICY_SECURITY_LOGGING,
+ caller.getPackageName(),
+ caller.getUserId());
+ final Boolean policy = mDevicePolicyEngine.getGlobalPolicySetByAdmin(
+ PolicyDefinition.SECURITY_LOGGING, enforcingAdmin);
+ return Boolean.TRUE.equals(policy);
+ } else {
+ synchronized (getLockObject()) {
+ if (admin != null) {
+ Preconditions.checkCallAuthorization(
+ isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || isDefaultDeviceOwner(caller));
} else {
- if (admin != null) {
- Preconditions.checkCallAuthorization(
- isProfileOwnerOfOrganizationOwnedDevice(caller)
- || isDefaultDeviceOwner(caller));
- } else {
- // A delegate app passes a null admin component, which is expected
- Preconditions.checkCallAuthorization(
- isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
- }
+ // A delegate app passes a null admin component, which is expected
+ Preconditions.checkCallAuthorization(
+ isCallerDelegate(caller, DELEGATION_SECURITY_LOGGING));
}
+ return mInjector.securityLogGetLoggingEnabledProperty();
}
- return mInjector.securityLogGetLoggingEnabledProperty();
}
}
@@ -17727,17 +17813,32 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
final CallerIdentity caller = getCallerIdentity(admin, packageName);
- if (isPermissionCheckFlagEnabled()) {
- Preconditions.checkCallAuthorization(isOrganizationOwnedDeviceWithManagedProfile()
- || areAllUsersAffiliatedWithDeviceLocked());
- enforcePermission(MANAGE_DEVICE_POLICY_SECURITY_LOGGING, caller.getPackageName(),
- UserHandle.USER_ALL);
+ if (securityLogV2Enabled()) {
+ EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin(
+ admin,
+ MANAGE_DEVICE_POLICY_SECURITY_LOGGING,
+ caller.getPackageName(),
+ caller.getUserId());
+
+ synchronized (getLockObject()) {
+ Preconditions.checkCallAuthorization(isOrganizationOwnedDeviceWithManagedProfile()
+ || areAllUsersAffiliatedWithDeviceLocked());
+ }
+
+ Boolean policy = mDevicePolicyEngine.getGlobalPolicySetByAdmin(
+ PolicyDefinition.SECURITY_LOGGING, enforcingAdmin);
+
+ if (!Boolean.TRUE.equals(policy)) {
+ Slogf.e(LOG_TAG, "%s hasn't enabled security logging but tries to retrieve logs",
+ caller.getPackageName());
+ return null;
+ }
} else {
if (admin != null) {
Preconditions.checkCallAuthorization(
isProfileOwnerOfOrganizationOwnedDevice(caller)
- || isDefaultDeviceOwner(caller));
+ || isDefaultDeviceOwner(caller));
} else {
// A delegate app passes a null admin component, which is expected
Preconditions.checkCallAuthorization(
@@ -17745,10 +17846,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
}
Preconditions.checkCallAuthorization(isOrganizationOwnedDeviceWithManagedProfile()
|| areAllUsersAffiliatedWithDeviceLocked());
- }
- if (!mInjector.securityLogGetLoggingEnabledProperty()) {
- return null;
+ if (!mInjector.securityLogGetLoggingEnabledProperty()) {
+ return null;
+ }
}
recordSecurityLogRetrievalTime();
@@ -17758,7 +17859,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
.createEvent(DevicePolicyEnums.RETRIEVE_SECURITY_LOGS)
.setAdmin(caller.getPackageName())
.write();
- return logs != null ? new ParceledListSlice<SecurityEvent>(logs) : null;
+ return logs != null ? new ParceledListSlice<>(logs) : null;
}
@Override
@@ -23477,10 +23578,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
return mInjector.binderWithCleanCallingIdentity(() -> {
boolean canForceMigration = forceMigration && !hasNonTestOnlyActiveAdmins();
- if (!canForceMigration && !shouldMigrateToDevicePolicyEngine()) {
+ if (!canForceMigration && !shouldMigrateV1ToDevicePolicyEngine()) {
return false;
}
- return migratePoliciesToDevicePolicyEngine();
+ return migrateV1PoliciesToDevicePolicyEngine();
});
}
@@ -23503,14 +23604,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
});
}
- private boolean shouldMigrateToDevicePolicyEngine() {
+ private boolean shouldMigrateV1ToDevicePolicyEngine() {
return mInjector.binderWithCleanCallingIdentity(() -> !mOwners.isMigratedToPolicyEngine());
}
/**
+ * Migrates the initial set of policies to use policy engine.
* @return {@code true} if policies were migrated successfully, {@code false} otherwise.
*/
- private boolean migratePoliciesToDevicePolicyEngine() {
+ private boolean migrateV1PoliciesToDevicePolicyEngine() {
return mInjector.binderWithCleanCallingIdentity(() -> {
try {
synchronized (getLockObject()) {
@@ -23537,6 +23639,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub {
});
}
+ /**
+ * Migrates the rest of policies to use policy engine.
+ */
+ @GuardedBy("getLockObject()")
+ private void migratePoliciesToPolicyEngineLocked() {
+ maybeMigrateSecurityLoggingPolicyLocked();
+ }
+
private void migrateAutoTimezonePolicy() {
Slogf.i(LOG_TAG, "Skipping Migration of AUTO_TIMEZONE policy to device policy engine,"
+ "as no way to identify if the value was set by the admin or the user.");
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
index bb275e45b55a..c5a98880ec84 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/Owners.java
@@ -616,6 +616,19 @@ class Owners {
}
}
+ void markSecurityLoggingMigrated() {
+ synchronized (mData) {
+ mData.mSecurityLoggingMigrated = true;
+ mData.writeDeviceOwner();
+ }
+ }
+
+ boolean isSecurityLoggingMigrated() {
+ synchronized (mData) {
+ return mData.mSecurityLoggingMigrated;
+ }
+ }
+
@GuardedBy("mData")
void pushToAppOpsLocked() {
if (!mSystemReady) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
index 37d4f95cac29..d9fef10ee41b 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/OwnersData.java
@@ -16,6 +16,7 @@
package com.android.server.devicepolicy;
import static android.app.admin.DevicePolicyManager.DEVICE_OWNER_TYPE_DEFAULT;
+import static android.app.admin.flags.Flags.securityLogV2Enabled;
import android.annotation.Nullable;
import android.app.admin.SystemUpdateInfo;
@@ -86,6 +87,7 @@ class OwnersData {
private static final String ATTR_DEVICE_OWNER_TYPE_VALUE = "value";
private static final String ATTR_MIGRATED_TO_POLICY_ENGINE = "migratedToPolicyEngine";
+ private static final String ATTR_SECURITY_LOG_MIGRATED = "securityLogMigrated";
// Internal state for the device owner package.
OwnerInfo mDeviceOwner;
@@ -113,6 +115,7 @@ class OwnersData {
private final PolicyPathProvider mPathProvider;
boolean mMigratedToPolicyEngine = false;
+ boolean mSecurityLoggingMigrated = false;
OwnersData(PolicyPathProvider pathProvider) {
mPathProvider = pathProvider;
@@ -397,6 +400,9 @@ class OwnersData {
out.startTag(null, TAG_POLICY_ENGINE_MIGRATION);
out.attributeBoolean(null, ATTR_MIGRATED_TO_POLICY_ENGINE, mMigratedToPolicyEngine);
+ if (securityLogV2Enabled()) {
+ out.attributeBoolean(null, ATTR_SECURITY_LOG_MIGRATED, mSecurityLoggingMigrated);
+ }
out.endTag(null, TAG_POLICY_ENGINE_MIGRATION);
}
@@ -457,6 +463,8 @@ class OwnersData {
case TAG_POLICY_ENGINE_MIGRATION:
mMigratedToPolicyEngine = parser.getAttributeBoolean(
null, ATTR_MIGRATED_TO_POLICY_ENGINE, false);
+ mSecurityLoggingMigrated = securityLogV2Enabled()
+ && parser.getAttributeBoolean(null, ATTR_SECURITY_LOG_MIGRATED, false);
break;
default:
Slog.e(TAG, "Unexpected tag: " + tag);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
index b09908e608ba..3474db3c7c1f 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
@@ -134,6 +134,13 @@ final class PolicyDefinition<V> {
permissionName));
}
+ static PolicyDefinition<Boolean> SECURITY_LOGGING = new PolicyDefinition<>(
+ new NoArgsPolicyKey(DevicePolicyIdentifiers.SECURITY_LOGGING_POLICY),
+ TRUE_MORE_RESTRICTIVE,
+ POLICY_FLAG_GLOBAL_ONLY_POLICY,
+ PolicyEnforcerCallbacks::enforceSecurityLogging,
+ new BooleanPolicySerializer());
+
static PolicyDefinition<LockTaskPolicy> LOCK_TASK = new PolicyDefinition<>(
new NoArgsPolicyKey(DevicePolicyIdentifiers.LOCK_TASK_POLICY),
new TopPriority<>(List.of(
@@ -356,6 +363,8 @@ final class PolicyDefinition<V> {
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.AUTO_TIMEZONE_POLICY, AUTO_TIMEZONE);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.PERMISSION_GRANT_POLICY,
GENERIC_PERMISSION_GRANT);
+ POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.SECURITY_LOGGING_POLICY,
+ SECURITY_LOGGING);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.LOCK_TASK_POLICY, LOCK_TASK);
POLICY_DEFINITIONS.put(DevicePolicyIdentifiers.USER_CONTROL_DISABLED_PACKAGES_POLICY,
USER_CONTROLLED_DISABLED_PACKAGES);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
index 506dbe8c48c4..4aaefa670ea2 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyEnforcerCallbacks.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.app.AppGlobals;
import android.app.admin.DevicePolicyCache;
import android.app.admin.DevicePolicyManager;
+import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.IntentFilterPolicyKey;
import android.app.admin.LockTaskPolicy;
import android.app.admin.PackagePermissionPolicyKey;
@@ -127,6 +128,14 @@ final class PolicyEnforcerCallbacks {
}
}
+ static boolean enforceSecurityLogging(
+ @Nullable Boolean value, @NonNull Context context, int userId,
+ @NonNull PolicyKey policyKey) {
+ final var dpmi = LocalServices.getService(DevicePolicyManagerInternal.class);
+ dpmi.enforceSecurityLoggingPolicy(Boolean.TRUE.equals(value));
+ return true;
+ }
+
static boolean setLockTask(
@Nullable LockTaskPolicy policy, @NonNull Context context, int userId) {
List<String> packages = Collections.emptyList();
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
index 939a3dcfa32d..7a4454b11fce 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/SecurityLogMonitor.java
@@ -101,6 +101,10 @@ class SecurityLogMonitor implements Runnable {
/** Minimum time between forced fetch attempts. */
private static final long FORCE_FETCH_THROTTLE_NS = TimeUnit.SECONDS.toNanos(10);
+ /**
+ * Monitor thread is not null iff SecurityLogMonitor is running, i.e. started and not stopped.
+ * Pausing doesn't change it.
+ */
@GuardedBy("mLock")
private Thread mMonitorThread = null;
@GuardedBy("mLock")
@@ -147,7 +151,6 @@ class SecurityLogMonitor implements Runnable {
void start(int enabledUser) {
Slog.i(TAG, "Starting security logging for user " + enabledUser);
mEnabledUser = enabledUser;
- SecurityLog.writeEvent(SecurityLog.TAG_LOGGING_STARTED);
mLock.lock();
try {
if (mMonitorThread == null) {
@@ -160,6 +163,11 @@ class SecurityLogMonitor implements Runnable {
mMonitorThread = new Thread(this);
mMonitorThread.start();
+
+ SecurityLog.writeEvent(SecurityLog.TAG_LOGGING_STARTED);
+ Slog.i(TAG, "Security log monitor thread started");
+ } else {
+ Slog.i(TAG, "Security log monitor thread is already running");
}
} finally {
mLock.unlock();