Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c3cd05f8 authored by Rubin Xu's avatar Rubin Xu
Browse files

Add DevicePolicyManager APIs for process logging.

Add Device Owner APIs for controlling and retrieving the logs. Retrieving the
logs should be rate limited unless we are at the risk of losing logs due to
constrained buffer space.

Bug: 22860162
Change-Id: I80658f5a14e86d7cfd42402fbc5e98dc11698c0e
parent 6b6c5a20
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -5783,6 +5783,7 @@ package android.app.admin {
    method public void onProfileProvisioningComplete(android.content.Context, android.content.Intent);
    method public deprecated void onReadyForUserInitialization(android.content.Context, android.content.Intent);
    method public void onReceive(android.content.Context, android.content.Intent);
    method public void onSecurityLogsAvailable(android.content.Context, android.content.Intent);
    method public void onSystemUpdatePending(android.content.Context, android.content.Intent, long);
    field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED";
    field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
@@ -5829,6 +5830,7 @@ package android.app.admin {
    method public boolean getCrossProfileContactsSearchDisabled(android.content.ComponentName);
    method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
    method public int getCurrentFailedPasswordAttempts();
    method public boolean getDeviceLoggingEnabled(android.content.ComponentName);
    method public java.lang.String getDeviceOwnerLockScreenInfo();
    method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
    method public int getKeyguardDisabledFeatures(android.content.ComponentName);
@@ -5885,6 +5887,8 @@ package android.app.admin {
    method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
    method public boolean requestBugreport(android.content.ComponentName);
    method public boolean resetPassword(java.lang.String, int);
    method public java.util.List<android.auditing.SecurityLog.SecurityEvent> retrieveDeviceLogs(android.content.ComponentName);
    method public java.util.List<android.auditing.SecurityLog.SecurityEvent> retrievePreviousDeviceLogs(android.content.ComponentName);
    method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
    method public boolean setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String);
    method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
@@ -5896,6 +5900,7 @@ package android.app.admin {
    method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
    method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
    method public void setCrossProfileContactsSearchDisabled(android.content.ComponentName, boolean);
    method public void setDeviceLoggingEnabled(android.content.ComponentName, boolean);
    method public boolean setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.String);
    method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
    method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
+5 −0
Original line number Diff line number Diff line
@@ -5919,6 +5919,7 @@ package android.app.admin {
    method public void onProfileProvisioningComplete(android.content.Context, android.content.Intent);
    method public deprecated void onReadyForUserInitialization(android.content.Context, android.content.Intent);
    method public void onReceive(android.content.Context, android.content.Intent);
    method public void onSecurityLogsAvailable(android.content.Context, android.content.Intent);
    method public void onSystemUpdatePending(android.content.Context, android.content.Intent, long);
    field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED";
    field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
@@ -5967,6 +5968,7 @@ package android.app.admin {
    method public int getCurrentFailedPasswordAttempts();
    method public deprecated java.lang.String getDeviceInitializerApp();
    method public deprecated android.content.ComponentName getDeviceInitializerComponent();
    method public boolean getDeviceLoggingEnabled(android.content.ComponentName);
    method public java.lang.String getDeviceOwner();
    method public java.lang.String getDeviceOwnerLockScreenInfo();
    method public java.lang.String getDeviceOwnerNameOnAnyUser();
@@ -6030,6 +6032,8 @@ package android.app.admin {
    method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
    method public boolean requestBugreport(android.content.ComponentName);
    method public boolean resetPassword(java.lang.String, int);
    method public java.util.List<android.auditing.SecurityLog.SecurityEvent> retrieveDeviceLogs(android.content.ComponentName);
    method public java.util.List<android.auditing.SecurityLog.SecurityEvent> retrievePreviousDeviceLogs(android.content.ComponentName);
    method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
    method public deprecated boolean setActiveProfileOwner(android.content.ComponentName, java.lang.String) throws java.lang.IllegalArgumentException;
    method public boolean setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String);
@@ -6042,6 +6046,7 @@ package android.app.admin {
    method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
    method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
    method public void setCrossProfileContactsSearchDisabled(android.content.ComponentName, boolean);
    method public void setDeviceLoggingEnabled(android.content.ComponentName, boolean);
    method public boolean setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.String);
    method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
    method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
+5 −0
Original line number Diff line number Diff line
@@ -5785,6 +5785,7 @@ package android.app.admin {
    method public void onProfileProvisioningComplete(android.content.Context, android.content.Intent);
    method public deprecated void onReadyForUserInitialization(android.content.Context, android.content.Intent);
    method public void onReceive(android.content.Context, android.content.Intent);
    method public void onSecurityLogsAvailable(android.content.Context, android.content.Intent);
    method public void onSystemUpdatePending(android.content.Context, android.content.Intent, long);
    field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLED = "android.app.action.DEVICE_ADMIN_DISABLED";
    field public static final java.lang.String ACTION_DEVICE_ADMIN_DISABLE_REQUESTED = "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED";
@@ -5831,6 +5832,7 @@ package android.app.admin {
    method public boolean getCrossProfileContactsSearchDisabled(android.content.ComponentName);
    method public java.util.List<java.lang.String> getCrossProfileWidgetProviders(android.content.ComponentName);
    method public int getCurrentFailedPasswordAttempts();
    method public boolean getDeviceLoggingEnabled(android.content.ComponentName);
    method public java.lang.String getDeviceOwnerLockScreenInfo();
    method public java.util.List<byte[]> getInstalledCaCerts(android.content.ComponentName);
    method public int getKeyguardDisabledFeatures(android.content.ComponentName);
@@ -5887,6 +5889,8 @@ package android.app.admin {
    method public boolean removeUser(android.content.ComponentName, android.os.UserHandle);
    method public boolean requestBugreport(android.content.ComponentName);
    method public boolean resetPassword(java.lang.String, int);
    method public java.util.List<android.auditing.SecurityLog.SecurityEvent> retrieveDeviceLogs(android.content.ComponentName);
    method public java.util.List<android.auditing.SecurityLog.SecurityEvent> retrievePreviousDeviceLogs(android.content.ComponentName);
    method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean);
    method public boolean setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String);
    method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean);
@@ -5898,6 +5902,7 @@ package android.app.admin {
    method public void setCertInstallerPackage(android.content.ComponentName, java.lang.String) throws java.lang.SecurityException;
    method public void setCrossProfileCallerIdDisabled(android.content.ComponentName, boolean);
    method public void setCrossProfileContactsSearchDisabled(android.content.ComponentName, boolean);
    method public void setDeviceLoggingEnabled(android.content.ComponentName, boolean);
    method public boolean setDeviceOwnerLockScreenInfo(android.content.ComponentName, java.lang.String);
    method public void setGlobalSetting(android.content.ComponentName, java.lang.String, java.lang.String);
    method public boolean setKeyguardDisabled(android.content.ComponentName, boolean);
+22 −0
Original line number Diff line number Diff line
@@ -265,6 +265,14 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
    public static final String ACTION_BUGREPORT_SHARE =
            "android.app.action.BUGREPORT_SHARE";

    /**
     * Broadcast action: notify that a new batch of device logs is ready to be collected.
     * @hide
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_SECURITY_LOGS_AVAILABLE
            = "android.app.action.SECURITY_LOGS_AVAILABLE";

    /**
     * A string containing the SHA-256 hash of the bugreport file.
     *
@@ -595,6 +603,18 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
            @BugreportFailureCode int failureCode) {
    }

    /**
     * Called when a new batch of device logs can be retrieved.
     *
     * <p>This callback is only applicable to device owners.
     *
     * @param context The running context as per {@link #onReceive}.
     * @param intent The received intent as per {@link #onReceive}.
     * @see DevicePolicyManager#retrieveDeviceLogs(ComponentName)
     */
    public void onSecurityLogsAvailable(Context context, Intent intent) {
    }

    /**
     * Intercept standard device administrator broadcasts.  Implementations
     * should not override this method; it is better to implement the
@@ -647,6 +667,8 @@ public class DeviceAdminReceiver extends BroadcastReceiver {
            int failureCode = intent.getIntExtra(EXTRA_BUGREPORT_FAILURE_REASON,
                    BUGREPORT_FAILURE_FAILED_COMPLETING);
            onBugreportFailed(context, intent, failureCode);
        } else if (ACTION_SECURITY_LOGS_AVAILABLE.equals(action)) {
            onSecurityLogsAvailable(context, intent);
        }
    }
}
+85 −1
Original line number Diff line number Diff line
@@ -23,12 +23,15 @@ import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.app.Activity;
import android.auditing.SecurityLog;
import android.auditing.SecurityLog.SecurityEvent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.content.pm.UserInfo;
import android.graphics.Bitmap;
@@ -2210,7 +2213,6 @@ public class DevicePolicyManager {
    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    public static final String ACTION_START_ENCRYPTION
            = "android.app.action.START_ENCRYPTION";

    /**
     * Widgets are enabled in keyguard
     */
@@ -5352,6 +5354,66 @@ public class DevicePolicyManager {
                throw new SecurityException("The current user does not have a parent profile.");
            }
            return new DevicePolicyManager(mContext, true);
        } catch (RemoteException e) {
            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, e);
            return null;
        }
    }

    /**
     * Called by device owner to control the device logging feature. Logging can only be
     * enabled on single user devices where the sole user is managed by the device owner.
     *
     * <p> Device logs contain various information intended for security auditing purposes.
     * See {@link SecurityEvent} for details.
     *
     * @param admin Which device owner this request is associated with.
     * @param enabled whether device logging should be enabled or not.
     * @see #retrieveDeviceLogs
     */
    public void setDeviceLoggingEnabled(@NonNull ComponentName admin, boolean enabled) {
        try {
            mService.setDeviceLoggingEnabled(admin, enabled);
        } catch (RemoteException re) {
            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
        }
    }

    /**
     * Return whether device logging is enabled or not by the device owner.
     *
     * @param admin Which device owner this request is associated with.
     * @return {@code true} if device logging is enabled by device owner, {@code false} otherwise.
     */
    public boolean getDeviceLoggingEnabled(@NonNull ComponentName admin) {
        try {
            return mService.getDeviceLoggingEnabled(admin);
        } catch (RemoteException re) {
            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
            return false;
        }
    }

    /**
     * Called by device owner to retrieve all new device logging entries since the last call to
     * this API after device boots.
     *
     * <p> Access to the logs is rate limited and it will only return new logs after the device
     * owner has been notified via {@link DeviceAdminReceiver#onSecurityLogsAvailable}.
     *
     * @param admin Which device owner this request is associated with.
     * @return the new batch of device logs which is a list of {@link SecurityEvent},
     * or {@code null} if rate limitation is exceeded or if logging is currently disabled.
     */
    public List<SecurityEvent> retrieveDeviceLogs(@NonNull ComponentName admin) {
        try {
            ParceledListSlice<SecurityEvent> list = mService.retrieveDeviceLogs(admin);
            if (list != null) {
                return list.getList();
            } else {
                // Rate limit exceeded.
                return null;
            }
        } catch (RemoteException re) {
            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
            return null;
@@ -5374,6 +5436,28 @@ public class DevicePolicyManager {
        return new DevicePolicyManager(mContext, true);
    }

    /**
     * Called by device owners to retrieve device logs from before the device's last reboot.
     *
     * <p>
     * <strong> The device logs are retrieved from a RAM region which is not guaranteed to be
     * corruption-free during power cycles, due to hardware variations and limitations. As a
     * result, this API is provided as best-effort and the returned logs may contain corrupted data.
     * </strong>
     *
     * @param admin Which device owner this request is associated with.
     * @return Device logs from before the latest reboot of the system.
     */
    public List<SecurityEvent> retrievePreviousDeviceLogs(@NonNull ComponentName admin) {
        try {
            ParceledListSlice<SecurityEvent> list = mService.retrievePreviousDeviceLogs(admin);
            return list.getList();
        } catch (RemoteException re) {
            Log.w(TAG, REMOTE_EXCEPTION_MESSAGE, re);
            return Collections.<SecurityEvent>emptyList();
        }
    }

    /**
     * Called by a profile owner of a managed profile to set the color used for customization.
     * This color is used as background color of the confirm credentials screen for that user.
Loading