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      */
isLoggingEnabled()452     public static native boolean isLoggingEnabled();
453 
454     /**
455      * @hide
456      */
setLoggingEnabledProperty(boolean enabled)457     public static void setLoggingEnabledProperty(boolean enabled) {
458         SystemProperties.set(PROPERTY_LOGGING_ENABLED, enabled ? "true" : "false");
459     }
460 
461     /**
462      * @hide
463      */
getLoggingEnabledProperty()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          */
SecurityEvent(byte[] data)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          */
SecurityEvent(Parcel source)487         /* package */ SecurityEvent(Parcel source) {
488             this(source.readLong(), source.createByteArray());
489         }
490 
491         /** @hide */
492         @TestApi
SecurityEvent(long id, byte[] data)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          */
getTimeNanos()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          */
getTag()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          */
getData()515         public Object getData() {
516             return mEvent.getData();
517         }
518 
519         /**
520          * @hide
521          */
setId(long id)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          */
getId()530         public long getId() {
531             return mId;
532         }
533 
534         /**
535          * Returns severity level for the event.
536          */
getLogLevel()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.
getSuccess()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
describeContents()593         public int describeContents() {
594             return 0;
595         }
596 
597         @Override
writeToParcel(Parcel dest, int flags)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
equals(Object o)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
hashCode()631         public int hashCode() {
632             return Objects.hash(mEvent, mId);
633         }
634     }
635     /**
636      * Retrieve all security logs and return immediately.
637      * @hide
638      */
readEvents(Collection<SecurityEvent> output)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      */
readEventsSince(long timestamp, Collection<SecurityEvent> output)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      */
readPreviousEvents(Collection<SecurityEvent> output)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      */
readEventsOnWrapping(long timestamp, Collection<SecurityEvent> output)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      */
writeEvent(int tag, String str)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      */
writeEvent(int tag, Object... payloads)676     public static native int writeEvent(int tag, Object... payloads);
677 }
678