1 /* 2 * Copyright (C) 2023 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 com.android.safetycenter.logging; 18 19 import static android.os.Build.VERSION_CODES.TIRAMISU; 20 21 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED; 22 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__ACTION__ISSUE_PRIMARY_ACTION_CLICKED; 23 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__ACTION__ISSUE_SECONDARY_ACTION_CLICKED; 24 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__ACTION__NOTIFICATION_DISMISSED; 25 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__ACTION__NOTIFICATION_POSTED; 26 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__ISSUE_STATE__ACTIVE; 27 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__NAVIGATION_SOURCE__SOURCE_UNKNOWN; 28 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED; 29 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; 30 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SENSOR__SENSOR_UNKNOWN; 31 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SEVERITY_LEVEL__SAFETY_SEVERITY_CRITICAL_WARNING; 32 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SEVERITY_LEVEL__SAFETY_SEVERITY_OK; 33 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SEVERITY_LEVEL__SAFETY_SEVERITY_RECOMMENDATION; 34 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__SEVERITY_LEVEL__SAFETY_SEVERITY_UNSPECIFIED; 35 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_INTERACTION_REPORTED__VIEW_TYPE__VIEW_TYPE_NOTIFICATION; 36 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED; 37 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__COMPLETE_GET_NEW_DATA; 38 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__COMPLETE_RESCAN; 39 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_UNKNOWN; 40 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__INLINE_ACTION; 41 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__SINGLE_SOURCE_GET_NEW_DATA; 42 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__SINGLE_SOURCE_RESCAN; 43 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__RESULT__ERROR; 44 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__RESULT__SUCCESS; 45 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__RESULT__TIMEOUT; 46 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED; 47 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; 48 import static com.android.permission.PermissionStatsLog.SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_UNKNOWN; 49 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED; 50 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__COLLECTION_TYPE__AUTOMATIC; 51 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__COLLECTION_TYPE__SOURCE_UPDATED; 52 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED; 53 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; 54 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_CRITICAL_WARNING; 55 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_LEVEL_UNKNOWN; 56 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_OK; 57 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_RECOMMENDATION; 58 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_UNSPECIFIED; 59 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__DATA_PROVIDED; 60 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__NO_DATA_PROVIDED; 61 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__REFRESH_ERROR; 62 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__REFRESH_TIMEOUT; 63 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__SOURCE_CLEARED; 64 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__SOURCE_ERROR; 65 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__SOURCE_STATE_UNKNOWN; 66 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__UPDATE_TYPE__REFRESH_RESPONSE; 67 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__UPDATE_TYPE__SELF_INITIATED; 68 import static com.android.permission.PermissionStatsLog.SAFETY_SOURCE_STATE_COLLECTED__UPDATE_TYPE__UPDATE_TYPE_UNKNOWN; 69 import static com.android.permission.PermissionStatsLog.SAFETY_STATE; 70 import static com.android.permission.PermissionStatsLog.SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_CRITICAL_WARNING; 71 import static com.android.permission.PermissionStatsLog.SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_LEVEL_UNKNOWN; 72 import static com.android.permission.PermissionStatsLog.SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_OK; 73 import static com.android.permission.PermissionStatsLog.SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_RECOMMENDATION; 74 75 import android.annotation.ElapsedRealtimeLong; 76 import android.annotation.IntDef; 77 import android.annotation.Nullable; 78 import android.safetycenter.SafetyCenterManager; 79 import android.safetycenter.SafetyCenterManager.RefreshRequestType; 80 import android.safetycenter.SafetyCenterStatus; 81 import android.safetycenter.SafetyEvent; 82 import android.safetycenter.SafetySourceData; 83 import android.util.Log; 84 import android.util.StatsEvent; 85 86 import androidx.annotation.RequiresApi; 87 88 import com.android.permission.PermissionStatsLog; 89 import com.android.safetycenter.SafetyCenterFlags; 90 91 import java.lang.annotation.Retention; 92 import java.lang.annotation.RetentionPolicy; 93 import java.math.BigInteger; 94 import java.security.MessageDigest; 95 import java.security.NoSuchAlgorithmException; 96 import java.time.Duration; 97 98 /** 99 * Marshalls and writes statsd atoms. Contains implementation details of how atom parameters are 100 * encoded and provides a better-typed interface for other classes to call. 101 * 102 * @hide 103 */ 104 @RequiresApi(TIRAMISU) 105 public final class SafetyCenterStatsdLogger { 106 107 private static final String TAG = "SafetyCenterStatsdLog"; 108 private static final long UNSET_SOURCE_ID = 0; 109 private static final long UNSET_ISSUE_TYPE_ID = 0; 110 private static final long UNSET_SESSION_ID = 0; 111 private static final long UNSET_SOURCE_GROUP_ID = 0; 112 private static final long UNSET_REFRESH_REASON = 0L; 113 private static final boolean UNSET_DATA_CHANGED = false; 114 private static final long UNSET_LAST_UPDATED_ELAPSED_TIME_MILLIS = 0L; 115 116 /** 117 * The different results for a system event reported by Safety Center. 118 * 119 * @hide 120 */ 121 @IntDef( 122 prefix = {"SAFETY_CENTER_SYSTEM_EVENT_REPORTED__RESULT__"}, 123 value = { 124 SAFETY_CENTER_SYSTEM_EVENT_REPORTED__RESULT__SUCCESS, 125 SAFETY_CENTER_SYSTEM_EVENT_REPORTED__RESULT__ERROR, 126 SAFETY_CENTER_SYSTEM_EVENT_REPORTED__RESULT__TIMEOUT 127 }) 128 @Retention(RetentionPolicy.SOURCE) 129 public @interface SystemEventResult {} 130 131 /** 132 * The different results for a system event reported by Safety Center. 133 * 134 * @hide 135 */ 136 @IntDef( 137 prefix = {"SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__"}, 138 value = { 139 SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__SOURCE_STATE_UNKNOWN, 140 SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__DATA_PROVIDED, 141 SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__NO_DATA_PROVIDED, 142 SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__REFRESH_TIMEOUT, 143 SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__REFRESH_ERROR, 144 SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__SOURCE_ERROR, 145 SAFETY_SOURCE_STATE_COLLECTED__SOURCE_STATE__SOURCE_CLEARED 146 }) 147 @Retention(RetentionPolicy.SOURCE) 148 public @interface SourceState {} 149 150 /** 151 * Creates a {@link PermissionStatsLog#SAFETY_STATE} {@link StatsEvent} with the given 152 * parameters. 153 */ createSafetyStateEvent( @afetyCenterStatus.OverallSeverityLevel int severityLevel, long openIssueCount, long dismissedIssueCount)154 static StatsEvent createSafetyStateEvent( 155 @SafetyCenterStatus.OverallSeverityLevel int severityLevel, 156 long openIssueCount, 157 long dismissedIssueCount) { 158 return PermissionStatsLog.buildStatsEvent( 159 SAFETY_STATE, 160 toSafetyStateOverallSeverityLevel(severityLevel), 161 openIssueCount, 162 dismissedIssueCount); 163 } 164 165 /** Writes a {@link PermissionStatsLog#SAFETY_SOURCE_STATE_COLLECTED} atom. */ writeSafetySourceStateCollected( String sourceId, boolean isManagedProfile, @Nullable @SafetySourceData.SeverityLevel Integer sourceSeverityLevel, long openIssuesCount, long dismissedIssuesCount, long duplicateFilteredOutIssuesCount, @SourceState int sourceState, @Nullable SafetyEvent safetyEvent, @Nullable @SafetyCenterManager.RefreshReason Integer refreshReason, boolean dataChanged, @Nullable @ElapsedRealtimeLong Long lastUpdatedElapsedTimeMillis)166 public static void writeSafetySourceStateCollected( 167 String sourceId, 168 boolean isManagedProfile, 169 @Nullable @SafetySourceData.SeverityLevel Integer sourceSeverityLevel, 170 long openIssuesCount, 171 long dismissedIssuesCount, 172 long duplicateFilteredOutIssuesCount, 173 @SourceState int sourceState, 174 @Nullable SafetyEvent safetyEvent, 175 @Nullable @SafetyCenterManager.RefreshReason Integer refreshReason, 176 boolean dataChanged, 177 @Nullable @ElapsedRealtimeLong Long lastUpdatedElapsedTimeMillis) { 178 if (!SafetyCenterFlags.getAllowStatsdLogging()) { 179 return; 180 } 181 int collectionType = 182 safetyEvent != null 183 ? SAFETY_SOURCE_STATE_COLLECTED__COLLECTION_TYPE__SOURCE_UPDATED 184 : SAFETY_SOURCE_STATE_COLLECTED__COLLECTION_TYPE__AUTOMATIC; 185 PermissionStatsLog.write( 186 SAFETY_SOURCE_STATE_COLLECTED, 187 idStringToLong(sourceId), 188 toSourceStateCollectedProfileType(isManagedProfile), 189 toSafetySourceStateCollectedSeverityLevel(sourceSeverityLevel), 190 openIssuesCount, 191 dismissedIssuesCount, 192 duplicateFilteredOutIssuesCount, 193 sourceState, 194 collectionType, 195 toSafetySourceStateCollectedCollectionType(safetyEvent), 196 refreshReason != null ? refreshReason : UNSET_REFRESH_REASON, 197 dataChanged, 198 lastUpdatedElapsedTimeMillis != null 199 ? lastUpdatedElapsedTimeMillis 200 : UNSET_LAST_UPDATED_ELAPSED_TIME_MILLIS); 201 } 202 203 /** 204 * Writes a {@link PermissionStatsLog#SAFETY_CENTER_SYSTEM_EVENT_REPORTED} atom of type {@code 205 * SINGLE_SOURCE_RESCAN} or {@code SINGLE_SOURCE_GET_DATA}. 206 */ writeSourceRefreshSystemEvent( @efreshRequestType int refreshType, String sourceId, boolean isManagedProfile, Duration duration, @SystemEventResult int result, long refreshReason, boolean dataChanged)207 public static void writeSourceRefreshSystemEvent( 208 @RefreshRequestType int refreshType, 209 String sourceId, 210 boolean isManagedProfile, 211 Duration duration, 212 @SystemEventResult int result, 213 long refreshReason, 214 boolean dataChanged) { 215 if (!SafetyCenterFlags.getAllowStatsdLogging()) { 216 return; 217 } 218 PermissionStatsLog.write( 219 SAFETY_CENTER_SYSTEM_EVENT_REPORTED, 220 toSourceRefreshEventType(refreshType), 221 idStringToLong(sourceId), 222 toSystemEventProfileType(isManagedProfile), 223 UNSET_ISSUE_TYPE_ID, 224 duration.toMillis(), 225 result, 226 refreshReason, 227 dataChanged); 228 } 229 230 /** 231 * Writes a {@link PermissionStatsLog#SAFETY_CENTER_SYSTEM_EVENT_REPORTED} atom of type {@code 232 * COMPLETE_RESCAN} or {@code COMPLETE_GET_DATA}. 233 */ writeWholeRefreshSystemEvent( @efreshRequestType int refreshType, Duration duration, @SystemEventResult int result, long refreshReason, boolean dataChanged)234 public static void writeWholeRefreshSystemEvent( 235 @RefreshRequestType int refreshType, 236 Duration duration, 237 @SystemEventResult int result, 238 long refreshReason, 239 boolean dataChanged) { 240 if (!SafetyCenterFlags.getAllowStatsdLogging()) { 241 return; 242 } 243 PermissionStatsLog.write( 244 SAFETY_CENTER_SYSTEM_EVENT_REPORTED, 245 toWholeRefreshEventType(refreshType), 246 UNSET_SOURCE_ID, 247 SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_UNKNOWN, 248 UNSET_ISSUE_TYPE_ID, 249 duration.toMillis(), 250 result, 251 refreshReason, 252 dataChanged); 253 } 254 255 /** 256 * Writes a {@link PermissionStatsLog#SAFETY_CENTER_SYSTEM_EVENT_REPORTED} atom of type {@code 257 * INLINE_ACTION}. 258 */ writeInlineActionSystemEvent( String sourceId, boolean isManagedProfile, @Nullable String issueTypeId, Duration duration, @SystemEventResult int result)259 public static void writeInlineActionSystemEvent( 260 String sourceId, 261 boolean isManagedProfile, 262 @Nullable String issueTypeId, 263 Duration duration, 264 @SystemEventResult int result) { 265 if (!SafetyCenterFlags.getAllowStatsdLogging()) { 266 return; 267 } 268 PermissionStatsLog.write( 269 SAFETY_CENTER_SYSTEM_EVENT_REPORTED, 270 SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__INLINE_ACTION, 271 idStringToLong(sourceId), 272 toSystemEventProfileType(isManagedProfile), 273 issueTypeId == null ? UNSET_ISSUE_TYPE_ID : idStringToLong(issueTypeId), 274 duration.toMillis(), 275 result, 276 UNSET_REFRESH_REASON, 277 UNSET_DATA_CHANGED); 278 } 279 280 /** 281 * Writes a {@link PermissionStatsLog#SAFETY_CENTER_INTERACTION_REPORTED} atom with the action 282 * {@code NOTIFICATION_POSTED}. 283 */ writeNotificationPostedEvent( String sourceId, boolean isManagedProfile, String issueTypeId, @SafetySourceData.SeverityLevel int sourceSeverityLevel)284 public static void writeNotificationPostedEvent( 285 String sourceId, 286 boolean isManagedProfile, 287 String issueTypeId, 288 @SafetySourceData.SeverityLevel int sourceSeverityLevel) { 289 writeNotificationInteractionReportedEvent( 290 SAFETY_CENTER_INTERACTION_REPORTED__ACTION__NOTIFICATION_POSTED, 291 sourceId, 292 isManagedProfile, 293 issueTypeId, 294 sourceSeverityLevel); 295 } 296 297 /** 298 * Writes a {@link PermissionStatsLog#SAFETY_CENTER_INTERACTION_REPORTED} atom with the action 299 * {@code NOTIFICATION_DISMISSED}. 300 */ writeNotificationDismissedEvent( String sourceId, boolean isManagedProfile, String issueTypeId, @SafetySourceData.SeverityLevel int sourceSeverityLevel)301 public static void writeNotificationDismissedEvent( 302 String sourceId, 303 boolean isManagedProfile, 304 String issueTypeId, 305 @SafetySourceData.SeverityLevel int sourceSeverityLevel) { 306 writeNotificationInteractionReportedEvent( 307 SAFETY_CENTER_INTERACTION_REPORTED__ACTION__NOTIFICATION_DISMISSED, 308 sourceId, 309 isManagedProfile, 310 issueTypeId, 311 sourceSeverityLevel); 312 } 313 314 /** 315 * Writes a {@link PermissionStatsLog#SAFETY_CENTER_INTERACTION_REPORTED} atom with the action 316 * {@code ISSUE_PRIMARY_ACTION_CLICKED} or {@code ISSUE_SECONDARY_ACTION_CLICKED}. 317 */ writeNotificationActionClickedEvent( String sourceId, boolean isManagedProfile, String issueTypeId, @SafetySourceData.SeverityLevel int sourceSeverityLevel, boolean isPrimaryAction)318 public static void writeNotificationActionClickedEvent( 319 String sourceId, 320 boolean isManagedProfile, 321 String issueTypeId, 322 @SafetySourceData.SeverityLevel int sourceSeverityLevel, 323 boolean isPrimaryAction) { 324 int action = 325 isPrimaryAction 326 ? SAFETY_CENTER_INTERACTION_REPORTED__ACTION__ISSUE_PRIMARY_ACTION_CLICKED 327 : SAFETY_CENTER_INTERACTION_REPORTED__ACTION__ISSUE_SECONDARY_ACTION_CLICKED; 328 writeNotificationInteractionReportedEvent( 329 action, sourceId, isManagedProfile, issueTypeId, sourceSeverityLevel); 330 } 331 writeNotificationInteractionReportedEvent( int interactionReportedAction, String sourceId, boolean isManagedProfile, String issueTypeId, @SafetySourceData.SeverityLevel int sourceSeverityLevel)332 private static void writeNotificationInteractionReportedEvent( 333 int interactionReportedAction, 334 String sourceId, 335 boolean isManagedProfile, 336 String issueTypeId, 337 @SafetySourceData.SeverityLevel int sourceSeverityLevel) { 338 if (!SafetyCenterFlags.getAllowStatsdLogging()) { 339 return; 340 } 341 PermissionStatsLog.write( 342 SAFETY_CENTER_INTERACTION_REPORTED, 343 UNSET_SESSION_ID, 344 interactionReportedAction, 345 SAFETY_CENTER_INTERACTION_REPORTED__VIEW_TYPE__VIEW_TYPE_NOTIFICATION, 346 SAFETY_CENTER_INTERACTION_REPORTED__NAVIGATION_SOURCE__SOURCE_UNKNOWN, 347 toInteractionReportedSeverityLevel(sourceSeverityLevel), 348 idStringToLong(sourceId), 349 toInteractionReportedProfileType(isManagedProfile), 350 idStringToLong(issueTypeId), 351 SAFETY_CENTER_INTERACTION_REPORTED__SENSOR__SENSOR_UNKNOWN, 352 UNSET_SOURCE_GROUP_ID, 353 SAFETY_CENTER_INTERACTION_REPORTED__ISSUE_STATE__ACTIVE); 354 } 355 356 /** 357 * Returns a {@link SystemEventResult} based on whether the given operation was {@code 358 * successful}. 359 */ 360 @SystemEventResult toSystemEventResult(boolean success)361 public static int toSystemEventResult(boolean success) { 362 return success 363 ? SAFETY_CENTER_SYSTEM_EVENT_REPORTED__RESULT__SUCCESS 364 : SAFETY_CENTER_SYSTEM_EVENT_REPORTED__RESULT__ERROR; 365 } 366 toSourceRefreshEventType(@efreshRequestType int refreshType)367 private static int toSourceRefreshEventType(@RefreshRequestType int refreshType) { 368 switch (refreshType) { 369 case SafetyCenterManager.EXTRA_REFRESH_REQUEST_TYPE_GET_DATA: 370 return SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__SINGLE_SOURCE_GET_NEW_DATA; 371 case SafetyCenterManager.EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA: 372 return SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__SINGLE_SOURCE_RESCAN; 373 } 374 Log.w(TAG, "Unexpected SafetyCenterManager.RefreshRequestType: " + refreshType); 375 return SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_UNKNOWN; 376 } 377 toWholeRefreshEventType(@efreshRequestType int refreshType)378 private static int toWholeRefreshEventType(@RefreshRequestType int refreshType) { 379 switch (refreshType) { 380 case SafetyCenterManager.EXTRA_REFRESH_REQUEST_TYPE_GET_DATA: 381 return SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__COMPLETE_GET_NEW_DATA; 382 case SafetyCenterManager.EXTRA_REFRESH_REQUEST_TYPE_FETCH_FRESH_DATA: 383 return SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__COMPLETE_RESCAN; 384 } 385 Log.w(TAG, "Unexpected SafetyCenterManager.RefreshRequestType: " + refreshType); 386 return SAFETY_CENTER_SYSTEM_EVENT_REPORTED__EVENT_TYPE__EVENT_TYPE_UNKNOWN; 387 } 388 toSourceStateCollectedProfileType(boolean isManagedProfile)389 private static int toSourceStateCollectedProfileType(boolean isManagedProfile) { 390 return isManagedProfile 391 ? SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED 392 : SAFETY_SOURCE_STATE_COLLECTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; 393 } 394 toSystemEventProfileType(boolean isManagedProfile)395 private static int toSystemEventProfileType(boolean isManagedProfile) { 396 return isManagedProfile 397 ? SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED 398 : SAFETY_CENTER_SYSTEM_EVENT_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; 399 } 400 toInteractionReportedProfileType(boolean isManagedProfile)401 private static int toInteractionReportedProfileType(boolean isManagedProfile) { 402 return isManagedProfile 403 ? SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_MANAGED 404 : SAFETY_CENTER_INTERACTION_REPORTED__SAFETY_SOURCE_PROFILE_TYPE__PROFILE_TYPE_PERSONAL; 405 } 406 407 /** 408 * Converts a {@link String} ID (e.g. a Safety Source ID) to a {@code long} suitable for logging 409 * to statsd. 410 */ idStringToLong(String id)411 private static long idStringToLong(String id) { 412 MessageDigest messageDigest; 413 try { 414 messageDigest = MessageDigest.getInstance("MD5"); 415 } catch (NoSuchAlgorithmException e) { 416 Log.w(TAG, "Couldn't encode safety source id: " + id, e); 417 return 0; 418 } 419 messageDigest.update(id.getBytes()); 420 return new BigInteger(messageDigest.digest()).longValue(); 421 } 422 toSafetyStateOverallSeverityLevel( @afetyCenterStatus.OverallSeverityLevel int severityLevel)423 private static int toSafetyStateOverallSeverityLevel( 424 @SafetyCenterStatus.OverallSeverityLevel int severityLevel) { 425 switch (severityLevel) { 426 case SafetyCenterStatus.OVERALL_SEVERITY_LEVEL_UNKNOWN: 427 return SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_LEVEL_UNKNOWN; 428 case SafetyCenterStatus.OVERALL_SEVERITY_LEVEL_OK: 429 return SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_OK; 430 case SafetyCenterStatus.OVERALL_SEVERITY_LEVEL_RECOMMENDATION: 431 return SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_RECOMMENDATION; 432 case SafetyCenterStatus.OVERALL_SEVERITY_LEVEL_CRITICAL_WARNING: 433 return SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_CRITICAL_WARNING; 434 } 435 Log.w(TAG, "Unexpected SafetyCenterStatus.OverallSeverityLevel: " + severityLevel); 436 return SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_LEVEL_UNKNOWN; 437 } 438 toSafetySourceStateCollectedSeverityLevel( @ullable @afetySourceData.SeverityLevel Integer safetySourceSeverityLevel)439 private static int toSafetySourceStateCollectedSeverityLevel( 440 @Nullable @SafetySourceData.SeverityLevel Integer safetySourceSeverityLevel) { 441 if (safetySourceSeverityLevel == null) { 442 return SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_LEVEL_UNKNOWN; 443 } 444 switch (safetySourceSeverityLevel) { 445 case SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED: 446 return SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_UNSPECIFIED; 447 case SafetySourceData.SEVERITY_LEVEL_INFORMATION: 448 return SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_OK; 449 case SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION: 450 return SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_RECOMMENDATION; 451 case SafetySourceData.SEVERITY_LEVEL_CRITICAL_WARNING: 452 return SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_CRITICAL_WARNING; 453 } 454 Log.w(TAG, "Unexpected SafetySourceData.SeverityLevel: " + safetySourceSeverityLevel); 455 return SAFETY_SOURCE_STATE_COLLECTED__SEVERITY_LEVEL__SAFETY_SEVERITY_LEVEL_UNKNOWN; 456 } 457 toInteractionReportedSeverityLevel( @afetySourceData.SeverityLevel int severityLevel)458 private static int toInteractionReportedSeverityLevel( 459 @SafetySourceData.SeverityLevel int severityLevel) { 460 switch (severityLevel) { 461 case SafetySourceData.SEVERITY_LEVEL_UNSPECIFIED: 462 return SAFETY_CENTER_INTERACTION_REPORTED__SEVERITY_LEVEL__SAFETY_SEVERITY_UNSPECIFIED; 463 case SafetySourceData.SEVERITY_LEVEL_INFORMATION: 464 return SAFETY_CENTER_INTERACTION_REPORTED__SEVERITY_LEVEL__SAFETY_SEVERITY_OK; 465 case SafetySourceData.SEVERITY_LEVEL_RECOMMENDATION: 466 return SAFETY_CENTER_INTERACTION_REPORTED__SEVERITY_LEVEL__SAFETY_SEVERITY_RECOMMENDATION; 467 case SafetySourceData.SEVERITY_LEVEL_CRITICAL_WARNING: 468 return SAFETY_CENTER_INTERACTION_REPORTED__SEVERITY_LEVEL__SAFETY_SEVERITY_CRITICAL_WARNING; 469 } 470 Log.w(TAG, "Unexpected SafetySourceData.SeverityLevel: " + severityLevel); 471 return SAFETY_STATE__OVERALL_SEVERITY_LEVEL__SAFETY_SEVERITY_LEVEL_UNKNOWN; 472 } 473 toSafetySourceStateCollectedCollectionType( @ullable SafetyEvent safetyEvent)474 private static int toSafetySourceStateCollectedCollectionType( 475 @Nullable SafetyEvent safetyEvent) { 476 if (safetyEvent == null) { 477 return SAFETY_SOURCE_STATE_COLLECTED__UPDATE_TYPE__UPDATE_TYPE_UNKNOWN; 478 } 479 if (safetyEvent.getType() == SafetyEvent.SAFETY_EVENT_TYPE_REFRESH_REQUESTED) { 480 return SAFETY_SOURCE_STATE_COLLECTED__UPDATE_TYPE__REFRESH_RESPONSE; 481 } else { 482 return SAFETY_SOURCE_STATE_COLLECTED__UPDATE_TYPE__SELF_INITIATED; 483 } 484 } 485 } 486