/*
 * 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,
            TAG_CRYPTO_SELF_TEST_COMPLETED,
    })
    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;

    /**
     * Indicates that cryptographic functionality self test has completed. The log entry contains an
     * {@code Integer} payload, indicating the result of the test (0 if the test failed, 1 if
     * succeeded) and accessible via {@link SecurityEvent#getData()}.
     */
    public static final int TAG_CRYPTO_SELF_TEST_COMPLETED =
            SecurityLogTags.SECURITY_CRYPTO_SELF_TEST_COMPLETED;

    /**
     * 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:
                case TAG_CRYPTO_SELF_TEST_COMPLETED:
                    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);
}
