Home | History | Annotate | Download | only in admin
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.app.admin;
     18 
     19 import android.annotation.IntDef;
     20 import android.annotation.TestApi;
     21 import android.content.ComponentName;
     22 import android.os.Parcel;
     23 import android.os.Parcelable;
     24 import android.os.SystemProperties;
     25 import android.util.EventLog.Event;
     26 
     27 import java.io.IOException;
     28 import java.lang.annotation.Retention;
     29 import java.lang.annotation.RetentionPolicy;
     30 import java.util.Collection;
     31 import java.util.Objects;
     32 
     33 /**
     34  * Definitions for working with security logs.
     35  *
     36  * <p>Device owner apps can control the logging with
     37  * {@link DevicePolicyManager#setSecurityLoggingEnabled}. When security logs are enabled, device
     38  * owner apps receive periodic callbacks from {@link DeviceAdminReceiver#onSecurityLogsAvailable},
     39  * at which time new batch of logs can be collected via
     40  * {@link DevicePolicyManager#retrieveSecurityLogs}. {@link SecurityEvent} describes the type and
     41  * format of security logs being collected.
     42  */
     43 public class SecurityLog {
     44 
     45     private static final String PROPERTY_LOGGING_ENABLED = "persist.logd.security";
     46 
     47     /** @hide */
     48     @Retention(RetentionPolicy.SOURCE)
     49     @IntDef(prefix = { "TAG_" }, value = {
     50             TAG_ADB_SHELL_INTERACTIVE,
     51             TAG_ADB_SHELL_CMD,
     52             TAG_SYNC_RECV_FILE,
     53             TAG_SYNC_SEND_FILE,
     54             TAG_APP_PROCESS_START,
     55             TAG_KEYGUARD_DISMISSED,
     56             TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT,
     57             TAG_KEYGUARD_SECURED,
     58             TAG_OS_STARTUP,
     59             TAG_OS_SHUTDOWN,
     60             TAG_LOGGING_STARTED,
     61             TAG_LOGGING_STOPPED,
     62             TAG_MEDIA_MOUNT,
     63             TAG_MEDIA_UNMOUNT,
     64             TAG_LOG_BUFFER_SIZE_CRITICAL,
     65             TAG_PASSWORD_EXPIRATION_SET,
     66             TAG_PASSWORD_COMPLEXITY_SET,
     67             TAG_PASSWORD_HISTORY_LENGTH_SET,
     68             TAG_MAX_SCREEN_LOCK_TIMEOUT_SET,
     69             TAG_MAX_PASSWORD_ATTEMPTS_SET,
     70             TAG_KEYGUARD_DISABLED_FEATURES_SET,
     71             TAG_REMOTE_LOCK,
     72             TAG_USER_RESTRICTION_ADDED,
     73             TAG_USER_RESTRICTION_REMOVED,
     74             TAG_WIPE_FAILURE,
     75             TAG_KEY_GENERATED,
     76             TAG_KEY_IMPORT,
     77             TAG_KEY_DESTRUCTION,
     78             TAG_CERT_AUTHORITY_INSTALLED,
     79             TAG_CERT_AUTHORITY_REMOVED,
     80             TAG_CRYPTO_SELF_TEST_COMPLETED,
     81             TAG_KEY_INTEGRITY_VIOLATION,
     82             TAG_CERT_VALIDATION_FAILURE,
     83     })
     84     public @interface SecurityLogTag {}
     85 
     86     /** @hide */
     87     @Retention(RetentionPolicy.SOURCE)
     88     @IntDef(prefix = { "LEVEL_" }, value = {
     89             LEVEL_INFO,
     90             LEVEL_WARNING,
     91             LEVEL_ERROR
     92     })
     93     public @interface SecurityLogLevel {}
     94 
     95     /**
     96      * Indicates that an ADB interactive shell was opened via "adb shell".
     97      * There is no extra payload in the log event.
     98      */
     99     public static final int TAG_ADB_SHELL_INTERACTIVE =
    100             SecurityLogTags.SECURITY_ADB_SHELL_INTERACTIVE;
    101 
    102     /**
    103      * Indicates that a shell command was issued over ADB via {@code adb shell <command>}
    104      * The log entry contains a {@code String} payload containing the shell command, accessible
    105      * via {@link SecurityEvent#getData()}.
    106      */
    107     public static final int TAG_ADB_SHELL_CMD = SecurityLogTags.SECURITY_ADB_SHELL_COMMAND;
    108 
    109     /**
    110      * Indicates that a file was pulled from the device via the adb daemon, for example via
    111      * {@code adb pull}. The log entry contains a {@code String} payload containing the path of the
    112      * pulled file on the device, accessible via {@link SecurityEvent#getData()}.
    113      */
    114     public static final int TAG_SYNC_RECV_FILE = SecurityLogTags.SECURITY_ADB_SYNC_RECV;
    115 
    116     /**
    117      * Indicates that a file was pushed to the device via the adb daemon, for example via
    118      * {@code adb push}. The log entry contains a {@code String} payload containing the destination
    119      * path of the pushed file, accessible via {@link SecurityEvent#getData()}.
    120      */
    121     public static final int TAG_SYNC_SEND_FILE = SecurityLogTags.SECURITY_ADB_SYNC_SEND;
    122 
    123     /**
    124      * Indicates that an app process was started. The log entry contains the following
    125      * information about the process encapsulated in an {@link Object} array, accessible via
    126      * {@link SecurityEvent#getData()}:
    127      * <li> [0] process name ({@code String})
    128      * <li> [1] exact start time in milliseconds according to {@code System.currentTimeMillis()}
    129      *      ({@code Long})
    130      * <li> [2] app uid ({@code Integer})
    131      * <li> [3] app pid ({@code Integer})
    132      * <li> [4] seinfo tag ({@code String})
    133      * <li> [5] SHA-256 hash of the base APK in hexadecimal ({@code String})
    134      */
    135     public static final int TAG_APP_PROCESS_START = SecurityLogTags.SECURITY_APP_PROCESS_START;
    136 
    137     /**
    138      * Indicates that keyguard has been dismissed.
    139      * There is no extra payload in the log event.
    140      */
    141     public static final int TAG_KEYGUARD_DISMISSED = SecurityLogTags.SECURITY_KEYGUARD_DISMISSED;
    142 
    143     /**
    144      * Indicates that there has been an authentication attempt to dismiss the keyguard. The log
    145      * entry contains the following information about the attempt encapsulated in an {@link Object}
    146      * array, accessible via {@link SecurityEvent#getData()}:
    147      * <li> [0] attempt result ({@code Integer}, 1 for successful, 0 for unsuccessful)
    148      * <li> [1] strength of authentication method ({@code Integer}, 1 if strong authentication
    149      *      method was used, 0 otherwise)
    150      */
    151     public static final int TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT =
    152             SecurityLogTags.SECURITY_KEYGUARD_DISMISS_AUTH_ATTEMPT;
    153 
    154     /**
    155      * Indicates that the device has been locked, either by the user or by a timeout. There is no
    156      * extra payload in the log event.
    157      */
    158     public static final int TAG_KEYGUARD_SECURED = SecurityLogTags.SECURITY_KEYGUARD_SECURED;
    159 
    160     /**
    161      * Indicates that the Android OS has started. The log entry contains the following information
    162      * about the startup time software integrity check encapsulated in an {@link Object} array,
    163      * accessible via {@link SecurityEvent#getData()}:
    164      * <li> [0] Verified Boot state ({@code String})
    165      * <li> [1] dm-verity mode ({@code String}).
    166      * <p>Verified Boot state can be one of the following:
    167      * <li> {@code green} indicates that there is a full chain of trust extending from the
    168      * bootloader to verified partitions including the bootloader, boot partition, and all verified
    169      * partitions.
    170      * <li> {@code yellow} indicates that the boot partition has been verified using the embedded
    171      * certificate and the signature is valid.
    172      * <li> {@code orange} indicates that the device may be freely modified. Device integrity is
    173      * left to the user to verify out-of-band.
    174      * <p>dm-verity mode can be one of the following:
    175      * <li> {@code enforcing} indicates that the device will be restarted when corruption is
    176      * detected.
    177      * <li> {@code eio} indicates that an I/O error will be returned for an attempt to read
    178      * corrupted data blocks.
    179      * For details see Verified Boot documentation.
    180      */
    181     public static final int TAG_OS_STARTUP = SecurityLogTags.SECURITY_OS_STARTUP;
    182 
    183     /**
    184      * Indicates that the Android OS has shutdown. There is no extra payload in the log event.
    185      */
    186     public static final int TAG_OS_SHUTDOWN = SecurityLogTags.SECURITY_OS_SHUTDOWN;
    187 
    188     /**
    189      * Indicates start-up of audit logging. There is no extra payload in the log event.
    190      */
    191     public static final int TAG_LOGGING_STARTED = SecurityLogTags.SECURITY_LOGGING_STARTED;
    192 
    193     /**
    194      * Indicates shutdown of audit logging. There is no extra payload in the log event.
    195      */
    196     public static final int TAG_LOGGING_STOPPED = SecurityLogTags.SECURITY_LOGGING_STOPPED;
    197 
    198     /**
    199      * Indicates that removable media has been mounted on the device. The log entry contains the
    200      * following information about the event, encapsulated in an {@link Object} array and
    201      * accessible via {@link SecurityEvent#getData()}:
    202      * <li> [0] mount point ({@code String})
    203      * <li> [1] volume label ({@code String}).
    204      */
    205     public static final int TAG_MEDIA_MOUNT = SecurityLogTags.SECURITY_MEDIA_MOUNTED;
    206 
    207     /**
    208      * Indicates that removable media was unmounted from the device. The log entry contains the
    209      * following information about the event, encapsulated in an {@link Object} array and
    210      * accessible via {@link SecurityEvent#getData()}:
    211      * <li> [0] mount point ({@code String})
    212      * <li> [1] volume label ({@code String}).
    213      */
    214     public static final int TAG_MEDIA_UNMOUNT = SecurityLogTags.SECURITY_MEDIA_UNMOUNTED;
    215 
    216     /**
    217      * Indicates that the audit log buffer has reached 90% of its capacity. There is no extra
    218      * payload in the log event.
    219      */
    220     public static final int TAG_LOG_BUFFER_SIZE_CRITICAL =
    221             SecurityLogTags.SECURITY_LOG_BUFFER_SIZE_CRITICAL;
    222 
    223     /**
    224      * Indicates that an admin has set a password expiration timeout. The log entry contains the
    225      * following information about the event, encapsulated in an {@link Object} array and accessible
    226      * via {@link SecurityEvent#getData()}:
    227      * <li> [0] admin package name ({@code String})
    228      * <li> [1] admin user ID ({@code Integer})
    229      * <li> [2] target user ID ({@code Integer})
    230      * <li> [3] new password expiration timeout in milliseconds ({@code Long}).
    231      * @see DevicePolicyManager#setPasswordExpirationTimeout(ComponentName, long)
    232      */
    233     public static final int TAG_PASSWORD_EXPIRATION_SET =
    234             SecurityLogTags.SECURITY_PASSWORD_EXPIRATION_SET;
    235 
    236     /**
    237      * Indicates that an admin has set a requirement for password complexity. The log entry contains
    238      * the following information about the event, encapsulated in an {@link Object} array and
    239      * accessible via {@link SecurityEvent#getData()}:
    240      * <li> [0] admin package name ({@code String})
    241      * <li> [1] admin user ID ({@code Integer})
    242      * <li> [2] target user ID ({@code Integer})
    243      * <li> [3] minimum password length ({@code Integer})
    244      * <li> [4] password quality constraint ({@code Integer})
    245      * <li> [5] minimum number of letters ({@code Integer})
    246      * <li> [6] minimum number of non-letters ({@code Integer})
    247      * <li> [7] minimum number of digits ({@code Integer})
    248      * <li> [8] minimum number of uppercase letters ({@code Integer})
    249      * <li> [9] minimum number of lowercase letters ({@code Integer})
    250      * <li> [10] minimum number of symbols ({@code Integer})
    251      *
    252      * @see DevicePolicyManager#setPasswordMinimumLength(ComponentName, int)
    253      * @see DevicePolicyManager#setPasswordQuality(ComponentName, int)
    254      * @see DevicePolicyManager#setPasswordMinimumLetters(ComponentName, int)
    255      * @see DevicePolicyManager#setPasswordMinimumNonLetter(ComponentName, int)
    256      * @see DevicePolicyManager#setPasswordMinimumLowerCase(ComponentName, int)
    257      * @see DevicePolicyManager#setPasswordMinimumUpperCase(ComponentName, int)
    258      * @see DevicePolicyManager#setPasswordMinimumNumeric(ComponentName, int)
    259      * @see DevicePolicyManager#setPasswordMinimumSymbols(ComponentName, int)
    260      */
    261     public static final int TAG_PASSWORD_COMPLEXITY_SET =
    262             SecurityLogTags.SECURITY_PASSWORD_COMPLEXITY_SET;
    263 
    264     /**
    265      * Indicates that an admin has set a password history length. The log entry contains the
    266      * following information about the event encapsulated in an {@link Object} array, accessible
    267      * via {@link SecurityEvent#getData()}:
    268      * <li> [0] admin package name ({@code String})
    269      * <li> [1] admin user ID ({@code Integer})
    270      * <li> [2] target user ID ({@code Integer})
    271      * <li> [3] new password history length value ({@code Integer})
    272      * @see DevicePolicyManager#setPasswordHistoryLength(ComponentName, int)
    273      */
    274     public static final int TAG_PASSWORD_HISTORY_LENGTH_SET =
    275             SecurityLogTags.SECURITY_PASSWORD_HISTORY_LENGTH_SET;
    276 
    277     /**
    278      * Indicates that an admin has set a maximum screen lock timeout. The log entry contains the
    279      * following information about the event encapsulated in an {@link Object} array, accessible
    280      * via {@link SecurityEvent#getData()}:
    281      * <li> [0] admin package name ({@code String})
    282      * <li> [1] admin user ID ({@code Integer})
    283      * <li> [2] target user ID ({@code Integer})
    284      * <li> [3] new screen lock timeout in milliseconds ({@code Long})
    285      * @see DevicePolicyManager#setMaximumTimeToLock(ComponentName, long)
    286      */
    287     public static final int TAG_MAX_SCREEN_LOCK_TIMEOUT_SET =
    288             SecurityLogTags.SECURITY_MAX_SCREEN_LOCK_TIMEOUT_SET;
    289 
    290     /**
    291      * Indicates that an admin has set a maximum number of failed password attempts before wiping
    292      * data. The log entry contains the following information about the event encapsulated in an
    293      * {@link Object} array, accessible via {@link SecurityEvent#getData()}:
    294      * <li> [0] admin package name ({@code String})
    295      * <li> [1] admin user ID ({@code Integer})
    296      * <li> [2] target user ID ({@code Integer})
    297      * <li> [3] new maximum number of failed password attempts ({@code Integer})
    298      * @see DevicePolicyManager#setMaximumFailedPasswordsForWipe(ComponentName, int)
    299      */
    300     public static final int TAG_MAX_PASSWORD_ATTEMPTS_SET =
    301             SecurityLogTags.SECURITY_MAX_PASSWORD_ATTEMPTS_SET;
    302 
    303     /**
    304      * Indicates that an admin has set disabled keyguard features. The log entry contains the
    305      * following information about the event encapsulated in an {@link Object} array, accessible via
    306      * {@link SecurityEvent#getData()}:
    307      * <li> [0] admin package name ({@code String})
    308      * <li> [1] admin user ID ({@code Integer})
    309      * <li> [2] target user ID ({@code Integer})
    310      * <li> [3] disabled keyguard feature mask ({@code Integer}).
    311      * @see DevicePolicyManager#setKeyguardDisabledFeatures(ComponentName, int)
    312      */
    313     public static final int TAG_KEYGUARD_DISABLED_FEATURES_SET =
    314             SecurityLogTags.SECURITY_KEYGUARD_DISABLED_FEATURES_SET;
    315 
    316     /**
    317      * Indicates that an admin remotely locked the device or profile. The log entry contains the
    318      * following information about the event encapsulated in an {@link Object} array, accessible via
    319      * {@link SecurityEvent#getData()}:
    320      * <li> [0] admin package name ({@code String}),
    321      * <li> [1] admin user ID ({@code Integer}).
    322      * <li> [2] target user ID ({@code Integer})
    323      */
    324     public static final int TAG_REMOTE_LOCK = SecurityLogTags.SECURITY_REMOTE_LOCK;
    325 
    326     /**
    327      * Indicates a failure to wipe device or user data. There is no extra payload in the log event.
    328      */
    329     public static final int TAG_WIPE_FAILURE = SecurityLogTags.SECURITY_WIPE_FAILED;
    330 
    331     /**
    332      * Indicates that an authentication key was generated. The log entry contains the following
    333      * information about the event, encapsulated in an {@link Object} array and accessible via
    334      * {@link SecurityEvent#getData()}:
    335      * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
    336      * <li> [1] alias of the key ({@code String})
    337      * <li> [2] requesting process uid ({@code Integer}).
    338      */
    339     public static final int TAG_KEY_GENERATED =
    340             SecurityLogTags.SECURITY_KEY_GENERATED;
    341 
    342     /**
    343      * Indicates that a cryptographic key was imported. The log entry contains the following
    344      * information about the event, encapsulated in an {@link Object} array and accessible via
    345      * {@link SecurityEvent#getData()}:
    346      * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
    347      * <li> [1] alias of the key ({@code String})
    348      * <li> [2] requesting process uid ({@code Integer}).
    349      */
    350     public static final int TAG_KEY_IMPORT = SecurityLogTags.SECURITY_KEY_IMPORTED;
    351 
    352     /**
    353      * Indicates that a cryptographic key was destroyed. The log entry contains the following
    354      * information about the event, encapsulated in an {@link Object} array and accessible via
    355      * {@link SecurityEvent#getData()}:
    356      * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
    357      * <li> [1] alias of the key ({@code String})
    358      * <li> [2] requesting process uid ({@code Integer}).
    359      */
    360     public static final int TAG_KEY_DESTRUCTION = SecurityLogTags.SECURITY_KEY_DESTROYED;
    361 
    362     /**
    363      * Indicates that a new root certificate has been installed into system's trusted credential
    364      * storage. The log entry contains the following information about the event, encapsulated in an
    365      * {@link Object} array and accessible via {@link SecurityEvent#getData()}:
    366      * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
    367      * <li> [1] subject of the certificate ({@code String}).
    368      */
    369     public static final int TAG_CERT_AUTHORITY_INSTALLED =
    370             SecurityLogTags.SECURITY_CERT_AUTHORITY_INSTALLED;
    371 
    372     /**
    373      * Indicates that a new root certificate has been removed from system's trusted credential
    374      * storage. The log entry contains the following information about the event, encapsulated in an
    375      * {@link Object} array and accessible via {@link SecurityEvent#getData()}:
    376      * <li> [0] result ({@code Integer}, 0 if operation failed, 1 if succeeded)
    377      * <li> [1] subject of the certificate ({@code String}).
    378      */
    379     public static final int TAG_CERT_AUTHORITY_REMOVED =
    380             SecurityLogTags.SECURITY_CERT_AUTHORITY_REMOVED;
    381 
    382     /**
    383      * Indicates that an admin has set a user restriction. The log entry contains the following
    384      * information about the event, encapsulated in an {@link Object} array and accessible via
    385      * {@link SecurityEvent#getData()}:
    386      * <li> [0] admin package name ({@code String})
    387      * <li> [1] admin user ID ({@code Integer})
    388      * <li> [2] user restriction ({@code String})
    389      * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
    390      */
    391     public static final int TAG_USER_RESTRICTION_ADDED =
    392             SecurityLogTags.SECURITY_USER_RESTRICTION_ADDED;
    393 
    394     /**
    395      * Indicates that an admin has removed a user restriction. The log entry contains the following
    396      * information about the event, encapsulated in an {@link Object} array and accessible via
    397      * {@link SecurityEvent#getData()}:
    398      * <li> [0] admin package name ({@code String})
    399      * <li> [1] admin user ID ({@code Integer})
    400      * <li> [2] user restriction ({@code String})
    401      * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
    402      */
    403     public static final int TAG_USER_RESTRICTION_REMOVED =
    404             SecurityLogTags.SECURITY_USER_RESTRICTION_REMOVED;
    405 
    406     /**
    407      * Indicates that cryptographic functionality self test has completed. The log entry contains an
    408      * {@code Integer} payload, indicating the result of the test (0 if the test failed, 1 if
    409      * succeeded) and accessible via {@link SecurityEvent#getData()}.
    410      */
    411     public static final int TAG_CRYPTO_SELF_TEST_COMPLETED =
    412             SecurityLogTags.SECURITY_CRYPTO_SELF_TEST_COMPLETED;
    413 
    414     /**
    415      * Indicates a failed cryptographic key integrity check. The log entry contains the following
    416      * information about the event, encapsulated in an {@link Object} array and accessible via
    417      * {@link SecurityEvent#getData()}:
    418      * <li> [0] alias of the key ({@code String})
    419      * <li> [1] owner application uid ({@code Integer}).
    420      */
    421     public static final int TAG_KEY_INTEGRITY_VIOLATION =
    422             SecurityLogTags.SECURITY_KEY_INTEGRITY_VIOLATION;
    423 
    424     /**
    425      * Indicates a failure to validate X.509v3 certificate. The log entry contains a {@code String}
    426      * payload indicating the failure reason, accessible via {@link SecurityEvent#getData()}.
    427      */
    428     public static final int TAG_CERT_VALIDATION_FAILURE =
    429             SecurityLogTags.SECURITY_CERT_VALIDATION_FAILURE;
    430 
    431     /**
    432      * Event severity level indicating that the event corresponds to normal workflow.
    433      */
    434     public static final int LEVEL_INFO = 1;
    435 
    436     /**
    437      * Event severity level indicating that the event may require admin attention.
    438      */
    439     public static final int LEVEL_WARNING = 2;
    440 
    441     /**
    442      * Event severity level indicating that the event requires urgent admin action.
    443      */
    444     public static final int LEVEL_ERROR = 3;
    445 
    446     /**
    447      * Returns if security logging is enabled. Log producers should only write new logs if this is
    448      * true. Under the hood this is the logical AND of whether device owner exists and whether
    449      * it enables logging by setting the system property {@link #PROPERTY_LOGGING_ENABLED}.
    450      * @hide
    451      */
    452     public static native boolean isLoggingEnabled();
    453 
    454     /**
    455      * @hide
    456      */
    457     public static void setLoggingEnabledProperty(boolean enabled) {
    458         SystemProperties.set(PROPERTY_LOGGING_ENABLED, enabled ? "true" : "false");
    459     }
    460 
    461     /**
    462      * @hide
    463      */
    464     public static boolean getLoggingEnabledProperty() {
    465         return SystemProperties.getBoolean(PROPERTY_LOGGING_ENABLED, false);
    466     }
    467 
    468     /**
    469      * A class representing a security event log entry.
    470      */
    471     public static final class SecurityEvent implements Parcelable {
    472         private Event mEvent;
    473         private long mId;
    474 
    475         /**
    476          * Constructor used by native classes to generate SecurityEvent instances.
    477          * @hide
    478          */
    479         /* package */ SecurityEvent(byte[] data) {
    480             this(0, data);
    481         }
    482 
    483         /**
    484          * Constructor used by Parcelable.Creator to generate SecurityEvent instances.
    485          * @hide
    486          */
    487         /* package */ SecurityEvent(Parcel source) {
    488             this(source.readLong(), source.createByteArray());
    489         }
    490 
    491         /** @hide */
    492         @TestApi
    493         public SecurityEvent(long id, byte[] data) {
    494             mId = id;
    495             mEvent = Event.fromBytes(data);
    496         }
    497 
    498         /**
    499          * Returns the timestamp in nano seconds when this event was logged.
    500          */
    501         public long getTimeNanos() {
    502             return mEvent.getTimeNanos();
    503         }
    504 
    505         /**
    506          * Returns the tag of this log entry, which specifies entry's semantics.
    507          */
    508         public @SecurityLogTag int getTag() {
    509             return mEvent.getTag();
    510         }
    511 
    512         /**
    513          * Returns the payload contained in this log entry or {@code null} if there is no payload.
    514          */
    515         public Object getData() {
    516             return mEvent.getData();
    517         }
    518 
    519         /**
    520          * @hide
    521          */
    522         public void setId(long id) {
    523             this.mId = id;
    524         }
    525 
    526         /**
    527          * Returns the id of the event, where the id monotonically increases for each event. The id
    528          * is reset when the device reboots, and when security logging is enabled.
    529          */
    530         public long getId() {
    531             return mId;
    532         }
    533 
    534         /**
    535          * Returns severity level for the event.
    536          */
    537         public @SecurityLogLevel int getLogLevel() {
    538             switch (mEvent.getTag()) {
    539                 case TAG_ADB_SHELL_INTERACTIVE:
    540                 case TAG_ADB_SHELL_CMD:
    541                 case TAG_SYNC_RECV_FILE:
    542                 case TAG_SYNC_SEND_FILE:
    543                 case TAG_APP_PROCESS_START:
    544                 case TAG_KEYGUARD_DISMISSED:
    545                 case TAG_KEYGUARD_SECURED:
    546                 case TAG_OS_STARTUP:
    547                 case TAG_OS_SHUTDOWN:
    548                 case TAG_LOGGING_STARTED:
    549                 case TAG_LOGGING_STOPPED:
    550                 case TAG_MEDIA_MOUNT:
    551                 case TAG_MEDIA_UNMOUNT:
    552                 case TAG_PASSWORD_EXPIRATION_SET:
    553                 case TAG_PASSWORD_COMPLEXITY_SET:
    554                 case TAG_PASSWORD_HISTORY_LENGTH_SET:
    555                 case TAG_MAX_SCREEN_LOCK_TIMEOUT_SET:
    556                 case TAG_MAX_PASSWORD_ATTEMPTS_SET:
    557                 case TAG_USER_RESTRICTION_ADDED:
    558                 case TAG_USER_RESTRICTION_REMOVED:
    559                     return LEVEL_INFO;
    560                 case TAG_CERT_AUTHORITY_REMOVED:
    561                 case TAG_CRYPTO_SELF_TEST_COMPLETED:
    562                     return getSuccess() ? LEVEL_INFO : LEVEL_ERROR;
    563                 case TAG_CERT_AUTHORITY_INSTALLED:
    564                 case TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT:
    565                 case TAG_KEY_IMPORT:
    566                 case TAG_KEY_DESTRUCTION:
    567                 case TAG_KEY_GENERATED:
    568                     return getSuccess() ? LEVEL_INFO : LEVEL_WARNING;
    569                 case TAG_LOG_BUFFER_SIZE_CRITICAL:
    570                 case TAG_WIPE_FAILURE:
    571                 case TAG_KEY_INTEGRITY_VIOLATION:
    572                     return LEVEL_ERROR;
    573                 case TAG_CERT_VALIDATION_FAILURE:
    574                     return LEVEL_WARNING;
    575                 default:
    576                     return LEVEL_INFO;
    577             }
    578         }
    579 
    580         // Success/failure if present is encoded as an integer in the first (0th) element of data.
    581         private boolean getSuccess() {
    582             final Object data = getData();
    583             if (data == null || !(data instanceof Object[])) {
    584                 return false;
    585             }
    586 
    587             final Object[] array = (Object[]) data;
    588             return array.length >= 1 && array[0] instanceof Integer && (Integer) array[0] != 0;
    589         }
    590 
    591 
    592         @Override
    593         public int describeContents() {
    594             return 0;
    595         }
    596 
    597         @Override
    598         public void writeToParcel(Parcel dest, int flags) {
    599             dest.writeLong(mId);
    600             dest.writeByteArray(mEvent.getBytes());
    601         }
    602 
    603         public static final Parcelable.Creator<SecurityEvent> CREATOR =
    604                 new Parcelable.Creator<SecurityEvent>() {
    605             @Override
    606             public SecurityEvent createFromParcel(Parcel source) {
    607                 return new SecurityEvent(source);
    608             }
    609 
    610             @Override
    611             public SecurityEvent[] newArray(int size) {
    612                 return new SecurityEvent[size];
    613             }
    614         };
    615 
    616         /**
    617          * @hide
    618          */
    619         @Override
    620         public boolean equals(Object o) {
    621             if (this == o) return true;
    622             if (o == null || getClass() != o.getClass()) return false;
    623             SecurityEvent other = (SecurityEvent) o;
    624             return mEvent.equals(other.mEvent) && mId == other.mId;
    625         }
    626 
    627         /**
    628          * @hide
    629          */
    630         @Override
    631         public int hashCode() {
    632             return Objects.hash(mEvent, mId);
    633         }
    634     }
    635     /**
    636      * Retrieve all security logs and return immediately.
    637      * @hide
    638      */
    639     public static native void readEvents(Collection<SecurityEvent> output) throws IOException;
    640 
    641     /**
    642      * Retrieve all security logs since the given timestamp in nanoseconds and return immediately.
    643      * @hide
    644      */
    645     public static native void readEventsSince(long timestamp, Collection<SecurityEvent> output)
    646             throws IOException;
    647 
    648     /**
    649      * Retrieve all security logs before the last reboot. May return corrupted data due to
    650      * unreliable pstore.
    651      * @hide
    652      */
    653     public static native void readPreviousEvents(Collection<SecurityEvent> output)
    654             throws IOException;
    655 
    656     /**
    657      * Retrieve all security logs whose timestamp is equal to or greater than the given timestamp in
    658      * nanoseconds. This method will block until either the last log earlier than the given
    659      * timestamp is about to be pruned, or after a 2-hour timeout has passed.
    660      * @hide
    661      */
    662     public static native void readEventsOnWrapping(long timestamp, Collection<SecurityEvent> output)
    663             throws IOException;
    664 
    665     /**
    666      * Write a log entry to the underlying storage, with a string payload.
    667      * @hide
    668      */
    669     public static native int writeEvent(int tag, String str);
    670 
    671     /**
    672      * Write a log entry to the underlying storage, with several payloads.
    673      * Supported types of payload are: integer, long, float, string plus array of supported types.
    674      * @hide
    675      */
    676     public static native int writeEvent(int tag, Object... payloads);
    677 }
    678