/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.app.admin;

import android.annotation.IntDef;
import android.annotation.TestApi;
import android.content.ComponentName;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemProperties;
import android.util.EventLog.Event;

import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collection;
import java.util.Objects;

/**
 * Definitions for working with security logs.
 *
 * <p>Device owner apps can control the logging with
 * {@link DevicePolicyManager#setSecurityLoggingEnabled}. When security logs are enabled, device
 * owner apps receive periodic callbacks from {@link DeviceAdminReceiver#onSecurityLogsAvailable},
 * at which time new batch of logs can be collected via
 * {@link DevicePolicyManager#retrieveSecurityLogs}. {@link SecurityEvent} describes the type and
 * format of security logs being collected.
 */
public class SecurityLog {

    private static final String PROPERTY_LOGGING_ENABLED = "persist.logd.security";

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "TAG_" }, value = {
            TAG_ADB_SHELL_INTERACTIVE,
            TAG_ADB_SHELL_CMD,
            TAG_SYNC_RECV_FILE,
            TAG_SYNC_SEND_FILE,
            TAG_APP_PROCESS_START,
            TAG_KEYGUARD_DISMISSED,
            TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT,
            TAG_KEYGUARD_SECURED,
            TAG_OS_STARTUP,
            TAG_OS_SHUTDOWN,
            TAG_LOGGING_STARTED,
            TAG_LOGGING_STOPPED,
            TAG_MEDIA_MOUNT,
            TAG_MEDIA_UNMOUNT,
            TAG_LOG_BUFFER_SIZE_CRITICAL,
            TAG_PASSWORD_EXPIRATION_SET,
            TAG_PASSWORD_COMPLEXITY_SET,
            TAG_PASSWORD_HISTORY_LENGTH_SET,
            TAG_MAX_SCREEN_LOCK_TIMEOUT_SET,
            TAG_MAX_PASSWORD_ATTEMPTS_SET,
            TAG_KEYGUARD_DISABLED_FEATURES_SET,
            TAG_REMOTE_LOCK,
            TAG_USER_RESTRICTION_ADDED,
            TAG_USER_RESTRICTION_REMOVED,
            TAG_WIPE_FAILURE,
            TAG_KEY_GENERATED,
            TAG_KEY_IMPORT,
            TAG_KEY_DESTRUCTION,
            TAG_CERT_AUTHORITY_INSTALLED,
            TAG_CERT_AUTHORITY_REMOVED,
    })
    public @interface SecurityLogTag {}

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = { "LEVEL_" }, value = {
            LEVEL_INFO,
            LEVEL_WARNING,
            LEVEL_ERROR
    })
    public @interface SecurityLogLevel {}

    /**
     * Indicates that an ADB interactive shell was opened via "adb shell".
     * There is no extra payload in the log event.
     */
    public static final int TAG_ADB_SHELL_INTERACTIVE =
            SecurityLogTags.SECURITY_ADB_SHELL_INTERACTIVE;

    /**
     * Indicates that a shell command was issued over ADB via {@code adb shell <command>}
     * The log entry contains a {@code String} payload containing the shell command, accessible
     * via {@link SecurityEvent#getData()}.
     */
    public static final int TAG_ADB_SHELL_CMD = SecurityLogTags.SECURITY_ADB_SHELL_COMMAND;

    /**
     * Indicates that a file was pulled from the device via the adb daemon, for example via
     * {@code adb pull}. The log entry contains a {@code String} payload containing the path of the
     * pulled file on the device, accessible via {@link SecurityEvent#getData()}.
     */
    public static final int TAG_SYNC_RECV_FILE = SecurityLogTags.SECURITY_ADB_SYNC_RECV;

    /**
     * Indicates that a file was pushed to the device via the adb daemon, for example via
     * {@code adb push}. The log entry contains a {@code String} payload containing the destination
     * path of the pushed file, accessible via {@link SecurityEvent#getData()}.
     */
    public static final int TAG_SYNC_SEND_FILE = SecurityLogTags.SECURITY_ADB_SYNC_SEND;

    /**
     * Indicates that an app process was started. The log entry contains the following
     * information about the process encapsulated in an {@link Object} array, accessible via
     * {@link SecurityEvent#getData()}:
     * <li> [0] process name ({@code String})
     * <li> [1] exact start time in milliseconds according to {@code System.currentTimeMillis()}
     *      ({@code Long})
     * <li> [2] app uid ({@code Integer})
     * <li> [3] app pid ({@code Integer})
     * <li> [4] seinfo tag ({@code String})
     * <li> [5] SHA-256 hash of the base APK in hexadecimal ({@code String})
     */
    public static final int TAG_APP_PROCESS_START = SecurityLogTags.SECURITY_APP_PROCESS_START;

    /**
     * Indicates that keyguard has been dismissed.
     * There is no extra payload in the log event.
     */
    public static final int TAG_KEYGUARD_DISMISSED = SecurityLogTags.SECURITY_KEYGUARD_DISMISSED;

    /**
     * Indicates that there has been an authentication attempt to dismiss the keyguard. The log
     * entry contains the following information about the attempt encapsulated in an {@link Object}
     * array, accessible via {@link SecurityEvent#getData()}:
     * <li> [0] attempt result ({@code Integer}, 1 for successful, 0 for unsuccessful)
     * <li> [1] strength of authentication method ({@code Integer}, 1 if strong authentication
     *      method was used, 0 otherwise)
     */
    public static final int TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT =
            SecurityLogTags.SECURITY_KEYGUARD_DISMISS_AUTH_ATTEMPT;

    /**
     * Indicates that the device has been locked, either by the user or by a timeout. There is no
     * extra payload in the log event.
     */
    public static final int TAG_KEYGUARD_SECURED = SecurityLogTags.SECURITY_KEYGUARD_SECURED;

    /**
     * Indicates that the Android OS has started. The log entry contains the following information
     * about the startup time software integrity check encapsulated in an {@link Object} array,
     * accessible via {@link SecurityEvent#getData()}:
     * <li> [0] Verified Boot state ({@code String})
     * <li> [1] dm-verity mode ({@code String}).
     * <p>Verified Boot state can be one of the following:
     * <li> {@code green} indicates that there is a full chain of trust extending from the
     * bootloader to verified partitions including the bootloader, boot partition, and all verified
     * partitions.
     * <li> {@code yellow} indicates that the boot partition has been verified using the embedded
     * certificate and the signature is valid.
     * <li> {@code orange} indicates that the device may be freely modified. Device integrity is
     * left to the user to verify out-of-band.
     * <p>dm-verity mode can be one of the following:
     * <li> {@code enforcing} indicates that the device will be restarted when corruption is
     * detected.
     * <li> {@code eio} indicates that an I/O error will be returned for an attempt to read
     * corrupted data blocks.
     * For details see Verified Boot documentation.
     */
    public static final int TAG_OS_STARTUP = SecurityLogTags.SECURITY_OS_STARTUP;

    /**
     * Indicates that the Android OS has shutdown. There is no extra payload in the log event.
     */
    public static final int TAG_OS_SHUTDOWN = SecurityLogTags.SECURITY_OS_SHUTDOWN;

    /**
     * Indicates start-up of audit logging. There is no extra payload in the log event.
     */
    public static final int TAG_LOGGING_STARTED = SecurityLogTags.SECURITY_LOGGING_STARTED;

    /**
     * Indicates shutdown of audit logging. There is no extra payload in the log event.
     */
    public static final int TAG_LOGGING_STOPPED = SecurityLogTags.SECURITY_LOGGING_STOPPED;

    /**
     * Indicates that removable media has been mounted on the device. The log entry contains the
     * following information about the event, encapsulated in an {@link Object} array and
     * accessible via {@link SecurityEvent#getData()}:
     * <li> [0] mount point ({@code String})
     * <li> [1] volume label ({@code String}).
     */
    public static final int TAG_MEDIA_MOUNT = SecurityLogTags.SECURITY_MEDIA_MOUNTED;

    /**
     * Indicates that removable media was unmounted from the device. The log entry contains the
     * following information about the event, encapsulated in an {@link Object} array and
     * accessible via {@link SecurityEvent#getData()}:
     * <li> [0] mount point ({@code String})
     * <li> [1] volume label ({@code String}).
     */
    public static final int TAG_MEDIA_UNMOUNT = SecurityLogTags.SECURITY_MEDIA_UNMOUNTED;

    /**
     * Indicates that the audit log buffer has reached 90% of its capacity. There is no extra
     * payload in the log event.
     */
    public static final int TAG_LOG_BUFFER_SIZE_CRITICAL =
            SecurityLogTags.SECURITY_LOG_BUFFER_SIZE_CRITICAL;

    /**
     * Indicates that an admin has set a password expiration timeout. 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] new password expiration timeout in milliseconds ({@code Long}).
     * @see DevicePolicyManager#setPasswordExpirationTimeout(ComponentName, long)
     */
    public static final int TAG_PASSWORD_EXPIRATION_SET =
            SecurityLogTags.SECURITY_PASSWORD_EXPIRATION_SET;

    /**
     * Indicates that an admin has set a requirement for password complexity. 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] minimum password length ({@code Integer})
     * <li> [4] password quality constraint ({@code Integer})
     * <li> [5] minimum number of letters ({@code Integer})
     * <li> [6] minimum number of non-letters ({@code Integer})
     * <li> [7] minimum number of digits ({@code Integer})
     * <li> [8] minimum number of uppercase letters ({@code Integer})
     * <li> [9] minimum number of lowercase letters ({@code Integer})
     * <li> [10] minimum number of symbols ({@code Integer})
     *
     * @see DevicePolicyManager#setPasswordMinimumLength(ComponentName, int)
     * @see DevicePolicyManager#setPasswordQuality(ComponentName, int)
     * @see DevicePolicyManager#setPasswordMinimumLetters(ComponentName, int)
     * @see DevicePolicyManager#setPasswordMinimumNonLetter(ComponentName, int)
     * @see DevicePolicyManager#setPasswordMinimumLowerCase(ComponentName, int)
     * @see DevicePolicyManager#setPasswordMinimumUpperCase(ComponentName, int)
     * @see DevicePolicyManager#setPasswordMinimumNumeric(ComponentName, int)
     * @see DevicePolicyManager#setPasswordMinimumSymbols(ComponentName, int)
     */
    public static final int TAG_PASSWORD_COMPLEXITY_SET =
            SecurityLogTags.SECURITY_PASSWORD_COMPLEXITY_SET;

    /**
     * Indicates that an admin has set a password history length. The log entry contains the
     * following information about the event encapsulated in an {@link Object} array, 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] new password history length value ({@code Integer})
     * @see DevicePolicyManager#setPasswordHistoryLength(ComponentName, int)
     */
    public static final int TAG_PASSWORD_HISTORY_LENGTH_SET =
            SecurityLogTags.SECURITY_PASSWORD_HISTORY_LENGTH_SET;

    /**
     * Indicates that an admin has set a maximum screen lock timeout. The log entry contains the
     * following information about the event encapsulated in an {@link Object} array, 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] new screen lock timeout in milliseconds ({@code Long})
     * @see DevicePolicyManager#setMaximumTimeToLock(ComponentName, long)
     */
    public static final int TAG_MAX_SCREEN_LOCK_TIMEOUT_SET =
            SecurityLogTags.SECURITY_MAX_SCREEN_LOCK_TIMEOUT_SET;

    /**
     * Indicates that an admin has set a maximum number of failed password attempts before wiping
     * data. The log entry contains the following information about the event encapsulated in an
     * {@link Object} array, 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] new maximum number of failed password attempts ({@code Integer})
     * @see DevicePolicyManager#setMaximumTimeToLock(ComponentName, long)
     */
    public static final int TAG_MAX_PASSWORD_ATTEMPTS_SET =
            SecurityLogTags.SECURITY_MAX_PASSWORD_ATTEMPTS_SET;

    /**
     * Indicates that an admin has set disabled keyguard features. The log entry contains the
     * following information about the event encapsulated in an {@link Object} array, 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] disabled keyguard feature mask ({@code Integer}).
     * @see DevicePolicyManager#setKeyguardDisabledFeatures(ComponentName, int)
     */
    public static final int TAG_KEYGUARD_DISABLED_FEATURES_SET =
            SecurityLogTags.SECURITY_KEYGUARD_DISABLED_FEATURES_SET;

    /**
     * Indicates that an admin remotely locked the device or profile. The log entry contains the
     * following information about the event encapsulated in an {@link Object} array, accessible via
     * {@link SecurityEvent#getData()}:
     * <li> [0] admin package name ({@code String}),
     * <li> [1] admin user ID ({@code Integer}).
     */
    public static final int TAG_REMOTE_LOCK = SecurityLogTags.SECURITY_REMOTE_LOCK;

    /**
     * Indicates a failure to wipe device or user data. There is no extra payload in the log event.
     */
    public static final int TAG_WIPE_FAILURE = SecurityLogTags.SECURITY_WIPE_FAILED;

    /**
     * Indicates that an authentication key was generated. The log entry contains the following
     * information about the event, encapsulated in an {@link Object} array and accessible via
     * {@link SecurityEvent#getData()}:
     * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
     * <li> [1] alias of the key ({@code String})
     * <li> [2] requesting process uid ({@code Integer}).
     */
    public static final int TAG_KEY_GENERATED =
            SecurityLogTags.SECURITY_KEY_GENERATED;

    /**
     * Indicates that a cryptographic key was imported. The log entry contains the following
     * information about the event, encapsulated in an {@link Object} array and accessible via
     * {@link SecurityEvent#getData()}:
     * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
     * <li> [1] alias of the key ({@code String})
     * <li> [2] requesting process uid ({@code Integer}).
     */
    public static final int TAG_KEY_IMPORT = SecurityLogTags.SECURITY_KEY_IMPORTED;

    /**
     * Indicates that a cryptographic key was destroyed. The log entry contains the following
     * information about the event, encapsulated in an {@link Object} array and accessible via
     * {@link SecurityEvent#getData()}:
     * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
     * <li> [1] alias of the key ({@code String})
     * <li> [2] requesting process uid ({@code Integer}).
     */
    public static final int TAG_KEY_DESTRUCTION = SecurityLogTags.SECURITY_KEY_DESTROYED;

    /**
     * Indicates that a new root certificate has been installed into system's trusted credential
     * storage. The log entry contains the following information about the event, encapsulated in an
     * {@link Object} array and accessible via {@link SecurityEvent#getData()}:
     * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
     * <li> [1] subject of the certificate ({@code String}).
     */
    public static final int TAG_CERT_AUTHORITY_INSTALLED =
            SecurityLogTags.SECURITY_CERT_AUTHORITY_INSTALLED;

    /**
     * Indicates that a new oot certificate has been removed from system's trusted credential
     * storage. The log entry contains the following information about the event, encapsulated in an
     * {@link Object} array and accessible via {@link SecurityEvent#getData()}:
     * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
     * <li> [1] subject of the certificate ({@code String}).
     */
    public static final int TAG_CERT_AUTHORITY_REMOVED =
            SecurityLogTags.SECURITY_CERT_AUTHORITY_REMOVED;

    /**
     * Indicates that an admin has set a user restriction. 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] user restriction ({@code String})
     * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
     */
    public static final int TAG_USER_RESTRICTION_ADDED =
            SecurityLogTags.SECURITY_USER_RESTRICTION_ADDED;

    /**
     * Indicates that an admin has removed a user restriction. 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] user restriction ({@code String})
     * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
     */
    public static final int TAG_USER_RESTRICTION_REMOVED =
            SecurityLogTags.SECURITY_USER_RESTRICTION_REMOVED;

    /**
     * Event severity level indicating that the event corresponds to normal workflow.
     */
    public static final int LEVEL_INFO = 1;

    /**
     * Event severity level indicating that the event may require admin attention.
     */
    public static final int LEVEL_WARNING = 2;

    /**
     * Event severity level indicating that the event requires urgent admin action.
     */
    public static final int LEVEL_ERROR = 3;

    /**
     * Returns if security logging is enabled. Log producers should only write new logs if this is
     * true. Under the hood this is the logical AND of whether device owner exists and whether
     * it enables logging by setting the system property {@link #PROPERTY_LOGGING_ENABLED}.
     * @hide
     */
    public static native boolean isLoggingEnabled();

    /**
     * @hide
     */
    public static void setLoggingEnabledProperty(boolean enabled) {
        SystemProperties.set(PROPERTY_LOGGING_ENABLED, enabled ? "true" : "false");
    }

    /**
     * @hide
     */
    public static boolean getLoggingEnabledProperty() {
        return SystemProperties.getBoolean(PROPERTY_LOGGING_ENABLED, false);
    }

    /**
     * A class representing a security event log entry.
     */
    public static final class SecurityEvent implements Parcelable {
        private Event mEvent;
        private long mId;

        /**
         * Constructor used by native classes to generate SecurityEvent instances.
         * @hide
         */
        /* package */ SecurityEvent(byte[] data) {
            this(0, data);
        }

        /**
         * Constructor used by Parcelable.Creator to generate SecurityEvent instances.
         * @hide
         */
        /* package */ SecurityEvent(Parcel source) {
            this(source.readLong(), source.createByteArray());
        }

        /** @hide */
        @TestApi
        public SecurityEvent(long id, byte[] data) {
            mId = id;
            mEvent = Event.fromBytes(data);
        }

        /**
         * Returns the timestamp in nano seconds when this event was logged.
         */
        public long getTimeNanos() {
            return mEvent.getTimeNanos();
        }

        /**
         * Returns the tag of this log entry, which specifies entry's semantics.
         */
        public @SecurityLogTag int getTag() {
            return mEvent.getTag();
        }

        /**
         * Returns the payload contained in this log entry or {@code null} if there is no payload.
         */
        public Object getData() {
            return mEvent.getData();
        }

        /**
         * @hide
         */
        public void setId(long id) {
            this.mId = id;
        }

        /**
         * Returns the id of the event, where the id monotonically increases for each event. The id
         * is reset when the device reboots, and when security logging is enabled.
         */
        public long getId() {
            return mId;
        }

        /**
         * Returns severity level for the event.
         */
        public @SecurityLogLevel int getLogLevel() {
            switch (mEvent.getTag()) {
                case TAG_ADB_SHELL_INTERACTIVE:
                case TAG_ADB_SHELL_CMD:
                case TAG_SYNC_RECV_FILE:
                case TAG_SYNC_SEND_FILE:
                case TAG_APP_PROCESS_START:
                case TAG_KEYGUARD_DISMISSED:
                case TAG_KEYGUARD_SECURED:
                case TAG_OS_STARTUP:
                case TAG_OS_SHUTDOWN:
                case TAG_LOGGING_STARTED:
                case TAG_LOGGING_STOPPED:
                case TAG_MEDIA_MOUNT:
                case TAG_MEDIA_UNMOUNT:
                case TAG_PASSWORD_EXPIRATION_SET:
                case TAG_PASSWORD_COMPLEXITY_SET:
                case TAG_PASSWORD_HISTORY_LENGTH_SET:
                case TAG_MAX_SCREEN_LOCK_TIMEOUT_SET:
                case TAG_MAX_PASSWORD_ATTEMPTS_SET:
                case TAG_USER_RESTRICTION_ADDED:
                case TAG_USER_RESTRICTION_REMOVED:
                    return LEVEL_INFO;
                case TAG_CERT_AUTHORITY_REMOVED:
                    return getSuccess() ? LEVEL_INFO : LEVEL_ERROR;
                case TAG_CERT_AUTHORITY_INSTALLED:
                case TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT:
                case TAG_KEY_IMPORT:
                case TAG_KEY_DESTRUCTION:
                case TAG_KEY_GENERATED:
                    return getSuccess() ? LEVEL_INFO : LEVEL_WARNING;
                case TAG_LOG_BUFFER_SIZE_CRITICAL:
                case TAG_WIPE_FAILURE:
                    return LEVEL_ERROR;
                default:
                    return LEVEL_INFO;
            }
        }

        // Success/failure if present is encoded as an integer in the first (0th) element of data.
        private boolean getSuccess() {
            final Object data = getData();
            if (data == null || !(data instanceof Object[])) {
                return false;
            }

            final Object[] array = (Object[]) data;
            return array.length >= 1 && array[0] instanceof Integer && (Integer) array[0] != 0;
        }


        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeLong(mId);
            dest.writeByteArray(mEvent.getBytes());
        }

        public static final Parcelable.Creator<SecurityEvent> CREATOR =
                new Parcelable.Creator<SecurityEvent>() {
            @Override
            public SecurityEvent createFromParcel(Parcel source) {
                return new SecurityEvent(source);
            }

            @Override
            public SecurityEvent[] newArray(int size) {
                return new SecurityEvent[size];
            }
        };

        /**
         * @hide
         */
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            SecurityEvent other = (SecurityEvent) o;
            return mEvent.equals(other.mEvent) && mId == other.mId;
        }

        /**
         * @hide
         */
        @Override
        public int hashCode() {
            return Objects.hash(mEvent, mId);
        }
    }
    /**
     * Retrieve all security logs and return immediately.
     * @hide
     */
    public static native void readEvents(Collection<SecurityEvent> output) throws IOException;

    /**
     * Retrieve all security logs since the given timestamp in nanoseconds and return immediately.
     * @hide
     */
    public static native void readEventsSince(long timestamp, Collection<SecurityEvent> output)
            throws IOException;

    /**
     * Retrieve all security logs before the last reboot. May return corrupted data due to
     * unreliable pstore.
     * @hide
     */
    public static native void readPreviousEvents(Collection<SecurityEvent> output)
            throws IOException;

    /**
     * Retrieve all security logs whose timestamp is equal to or greater than the given timestamp in
     * nanoseconds. This method will block until either the last log earlier than the given
     * timestamp is about to be pruned, or after a 2-hour timeout has passed.
     * @hide
     */
    public static native void readEventsOnWrapping(long timestamp, Collection<SecurityEvent> output)
            throws IOException;

    /**
     * Write a log entry to the underlying storage, with a string payload.
     * @hide
     */
    public static native int writeEvent(int tag, String str);

    /**
     * Write a log entry to the underlying storage, with several payloads.
     * Supported types of payload are: integer, long, float, string plus array of supported types.
     * @hide
     */
    public static native int writeEvent(int tag, Object... payloads);
}
