1 /* 2 * Copyright (C) 2022 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.keyguard.logging 18 19 import android.content.Intent 20 import android.hardware.biometrics.BiometricConstants.LockoutMode 21 import android.hardware.biometrics.BiometricSourceType 22 import android.os.PowerManager 23 import android.os.PowerManager.WakeReason 24 import android.telephony.ServiceState 25 import android.telephony.SubscriptionInfo 26 import android.telephony.SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX 27 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID 28 import android.telephony.TelephonyManager 29 import com.android.keyguard.ActiveUnlockConfig 30 import com.android.keyguard.FaceAuthUiEvent 31 import com.android.keyguard.KeyguardListenModel 32 import com.android.keyguard.KeyguardUpdateMonitorCallback 33 import com.android.keyguard.TrustGrantFlags 34 import com.android.settingslib.fuelgauge.BatteryStatus 35 import com.android.systemui.log.LogBuffer 36 import com.android.systemui.log.core.LogLevel 37 import com.android.systemui.log.core.LogLevel.DEBUG 38 import com.android.systemui.log.core.LogLevel.ERROR 39 import com.android.systemui.log.core.LogLevel.INFO 40 import com.android.systemui.log.core.LogLevel.VERBOSE 41 import com.android.systemui.log.core.LogLevel.WARNING 42 import com.android.systemui.log.dagger.KeyguardUpdateMonitorLog 43 import com.google.errorprone.annotations.CompileTimeConstant 44 import javax.inject.Inject 45 46 private const val TAG = "KeyguardUpdateMonitorLog" 47 48 /** Helper class for logging for [com.android.keyguard.KeyguardUpdateMonitor] */ 49 class KeyguardUpdateMonitorLogger 50 @Inject 51 constructor(@KeyguardUpdateMonitorLog private val logBuffer: LogBuffer) { 52 fun d(@CompileTimeConstant msg: String) = log(msg, DEBUG) 53 54 fun e(@CompileTimeConstant msg: String) = log(msg, ERROR) 55 56 fun v(@CompileTimeConstant msg: String) = log(msg, VERBOSE) 57 58 fun w(@CompileTimeConstant msg: String) = log(msg, WARNING) 59 60 fun log(@CompileTimeConstant msg: String, level: LogLevel) = logBuffer.log(TAG, level, msg) 61 62 fun logActiveUnlockTriggered(reason: String?) { 63 logBuffer.log( 64 "ActiveUnlock", 65 DEBUG, 66 { str1 = reason }, 67 { "initiate active unlock triggerReason=$str1" } 68 ) 69 } 70 71 fun logActiveUnlockRequestSkippedForWakeReasonDueToFaceConfig(wakeReason: Int) { 72 logBuffer.log( 73 "ActiveUnlock", 74 DEBUG, 75 { int1 = wakeReason }, 76 { 77 "Skip requesting active unlock from wake reason that doesn't trigger face auth" + 78 " reason=${PowerManager.wakeReasonToString(int1)}" 79 } 80 ) 81 } 82 83 fun logAuthInterruptDetected(active: Boolean) { 84 logBuffer.log(TAG, DEBUG, { bool1 = active }, { "onAuthInterruptDetected($bool1)" }) 85 } 86 87 fun logBroadcastReceived(action: String?) { 88 logBuffer.log(TAG, DEBUG, { str1 = action }, { "received broadcast $str1" }) 89 } 90 91 fun logDeviceProvisionedState(deviceProvisioned: Boolean) { 92 logBuffer.log( 93 TAG, 94 DEBUG, 95 { bool1 = deviceProvisioned }, 96 { "DEVICE_PROVISIONED state = $bool1" } 97 ) 98 } 99 100 fun logException(ex: Exception, @CompileTimeConstant logMsg: String) { 101 logBuffer.log(TAG, ERROR, {}, { logMsg }, exception = ex) 102 } 103 104 fun logFaceAuthDisabledForUser(userId: Int) { 105 logBuffer.log( 106 TAG, 107 DEBUG, 108 { int1 = userId }, 109 { "Face authentication disabled by DPM for userId: $int1" } 110 ) 111 } 112 fun logFaceAuthError(msgId: Int, originalErrMsg: String) { 113 logBuffer.log( 114 TAG, 115 DEBUG, 116 { 117 str1 = originalErrMsg 118 int1 = msgId 119 }, 120 { "Face error received: $str1 msgId= $int1" } 121 ) 122 } 123 124 fun logFaceAuthForWrongUser(authUserId: Int) { 125 logBuffer.log( 126 TAG, 127 DEBUG, 128 { int1 = authUserId }, 129 { "Face authenticated for wrong user: $int1" } 130 ) 131 } 132 133 fun logFaceAuthRequested(reason: String?) { 134 logBuffer.log(TAG, DEBUG, { str1 = reason }, { "requestFaceAuth() reason=$str1" }) 135 } 136 137 fun logFaceAuthSuccess(userId: Int) { 138 logBuffer.log(TAG, DEBUG, { int1 = userId }, { "Face auth succeeded for user $int1" }) 139 } 140 141 fun logFaceLockoutReset(@LockoutMode mode: Int) { 142 logBuffer.log(TAG, DEBUG, { int1 = mode }, { "handleFaceLockoutReset: $int1" }) 143 } 144 145 fun logFaceRunningState(faceRunningState: Int) { 146 logBuffer.log(TAG, DEBUG, { int1 = faceRunningState }, { "faceRunningState: $int1" }) 147 } 148 149 fun logFaceUnlockPossible(isFaceUnlockPossible: Boolean) { 150 logBuffer.log( 151 TAG, 152 DEBUG, 153 { bool1 = isFaceUnlockPossible }, 154 { "isUnlockWithFacePossible: $bool1" } 155 ) 156 } 157 158 fun logFingerprintAuthForWrongUser(authUserId: Int) { 159 logBuffer.log( 160 TAG, 161 DEBUG, 162 { int1 = authUserId }, 163 { "Fingerprint authenticated for wrong user: $int1" } 164 ) 165 } 166 167 fun logFingerprintDisabledForUser(userId: Int) { 168 logBuffer.log( 169 TAG, 170 DEBUG, 171 { int1 = userId }, 172 { "Fingerprint disabled by DPM for userId: $int1" } 173 ) 174 } 175 176 fun logFingerprintLockoutReset(@LockoutMode mode: Int) { 177 logBuffer.log(TAG, DEBUG, { int1 = mode }, { "handleFingerprintLockoutReset: $int1" }) 178 } 179 180 fun logFingerprintRunningState(fingerprintRunningState: Int) { 181 logBuffer.log( 182 TAG, 183 DEBUG, 184 { int1 = fingerprintRunningState }, 185 { "fingerprintRunningState: $int1" } 186 ) 187 } 188 189 fun logFingerprintSuccess(userId: Int, isStrongBiometric: Boolean) { 190 logBuffer.log( 191 TAG, 192 DEBUG, 193 { 194 int1 = userId 195 bool1 = isStrongBiometric 196 }, 197 { "Fingerprint auth successful: userId: $int1, isStrongBiometric: $bool1" } 198 ) 199 } 200 201 fun logFaceDetected(userId: Int, isStrongBiometric: Boolean) { 202 logBuffer.log( 203 TAG, 204 DEBUG, 205 { 206 int1 = userId 207 bool1 = isStrongBiometric 208 }, 209 { "Face detected: userId: $int1, isStrongBiometric: $bool1" } 210 ) 211 } 212 213 fun logFingerprintDetected(userId: Int, isStrongBiometric: Boolean) { 214 logBuffer.log( 215 TAG, 216 DEBUG, 217 { 218 int1 = userId 219 bool1 = isStrongBiometric 220 }, 221 { "Fingerprint detected: userId: $int1, isStrongBiometric: $bool1" } 222 ) 223 } 224 225 fun logFingerprintError(msgId: Int, originalErrMsg: String) { 226 logBuffer.log( 227 TAG, 228 DEBUG, 229 { 230 str1 = originalErrMsg 231 int1 = msgId 232 }, 233 { "Fingerprint error received: $str1 msgId= $int1" } 234 ) 235 } 236 237 fun logInvalidSubId(subId: Int) { 238 logBuffer.log( 239 TAG, 240 INFO, 241 { int1 = subId }, 242 { "Previously active sub id $int1 is now invalid, will remove" } 243 ) 244 } 245 246 fun logPrimaryKeyguardBouncerChanged( 247 primaryBouncerIsOrWillBeShowing: Boolean, 248 primaryBouncerFullyShown: Boolean 249 ) { 250 logBuffer.log( 251 TAG, 252 DEBUG, 253 { 254 bool1 = primaryBouncerIsOrWillBeShowing 255 bool2 = primaryBouncerFullyShown 256 }, 257 { 258 "handlePrimaryBouncerChanged " + 259 "primaryBouncerIsOrWillBeShowing=$bool1 primaryBouncerFullyShown=$bool2" 260 } 261 ) 262 } 263 264 fun logKeyguardListenerModel(model: KeyguardListenModel) { 265 logBuffer.log(TAG, VERBOSE, { str1 = "$model" }, { str1!! }) 266 } 267 268 fun logKeyguardShowingChanged(showing: Boolean, occluded: Boolean, visible: Boolean) { 269 logBuffer.log( 270 TAG, 271 DEBUG, 272 { 273 bool1 = showing 274 bool2 = occluded 275 bool3 = visible 276 }, 277 { "keyguardShowingChanged(showing=$bool1 occluded=$bool2 visible=$bool3)" } 278 ) 279 } 280 281 fun logMissingSupervisorAppError(userId: Int) { 282 logBuffer.log( 283 TAG, 284 ERROR, 285 { int1 = userId }, 286 { "No Profile Owner or Device Owner supervision app found for User $int1" } 287 ) 288 } 289 290 fun logPhoneStateChanged(newState: String?) { 291 logBuffer.log(TAG, DEBUG, { str1 = newState }, { "handlePhoneStateChanged($str1)" }) 292 } 293 294 fun logRegisterCallback(callback: KeyguardUpdateMonitorCallback?) { 295 logBuffer.log(TAG, VERBOSE, { str1 = "$callback" }, { "*** register callback for $str1" }) 296 } 297 298 fun logRetryingAfterFaceHwUnavailable(retryCount: Int) { 299 logBuffer.log( 300 TAG, 301 WARNING, 302 { int1 = retryCount }, 303 { "Retrying face after HW unavailable, attempt $int1" } 304 ) 305 } 306 307 fun logRetryAfterFpErrorWithDelay(msgId: Int, errString: String?, delay: Int) { 308 logBuffer.log( 309 TAG, 310 DEBUG, 311 { 312 int1 = msgId 313 int2 = delay 314 str1 = "$errString" 315 }, 316 { "Fingerprint scheduling retry auth after $int2 ms due to($int1) -> $str1" } 317 ) 318 } 319 320 fun logRetryAfterFpHwUnavailable(retryCount: Int) { 321 logBuffer.log( 322 TAG, 323 WARNING, 324 { int1 = retryCount }, 325 { "Retrying fingerprint attempt: $int1" } 326 ) 327 } 328 329 fun logSendPrimaryBouncerChanged( 330 primaryBouncerIsOrWillBeShowing: Boolean, 331 primaryBouncerFullyShown: Boolean, 332 ) { 333 logBuffer.log( 334 TAG, 335 DEBUG, 336 { 337 bool1 = primaryBouncerIsOrWillBeShowing 338 bool2 = primaryBouncerFullyShown 339 }, 340 { 341 "sendPrimaryBouncerChanged primaryBouncerIsOrWillBeShowing=$bool1 " + 342 "primaryBouncerFullyShown=$bool2" 343 } 344 ) 345 } 346 347 fun logServiceStateChange(subId: Int, serviceState: ServiceState?) { 348 logBuffer.log( 349 TAG, 350 DEBUG, 351 { 352 int1 = subId 353 str1 = "$serviceState" 354 }, 355 { "handleServiceStateChange(subId=$int1, serviceState=$str1)" } 356 ) 357 } 358 359 fun logServiceStateIntent(action: String?, serviceState: ServiceState?, subId: Int) { 360 logBuffer.log( 361 TAG, 362 VERBOSE, 363 { 364 str1 = action 365 str2 = "$serviceState" 366 int1 = subId 367 }, 368 { "action $str1 serviceState=$str2 subId=$int1" } 369 ) 370 } 371 372 fun logServiceProvidersUpdated(intent: Intent) { 373 logBuffer.log( 374 TAG, 375 VERBOSE, 376 { 377 int1 = intent.getIntExtra(EXTRA_SUBSCRIPTION_INDEX, INVALID_SUBSCRIPTION_ID) 378 str1 = intent.getStringExtra(TelephonyManager.EXTRA_SPN) 379 str2 = intent.getStringExtra(TelephonyManager.EXTRA_PLMN) 380 }, 381 { "action SERVICE_PROVIDERS_UPDATED subId=$int1 spn=$str1 plmn=$str2" } 382 ) 383 } 384 385 fun logSimState(subId: Int, slotId: Int, state: Int) { 386 logBuffer.log( 387 TAG, 388 DEBUG, 389 { 390 int1 = subId 391 int2 = slotId 392 long1 = state.toLong() 393 }, 394 { "handleSimStateChange(subId=$int1, slotId=$int2, state=$long1)" } 395 ) 396 } 397 398 fun logSimStateFromIntent(action: String?, extraSimState: String?, slotId: Int, subId: Int) { 399 logBuffer.log( 400 TAG, 401 VERBOSE, 402 { 403 str1 = action 404 str2 = extraSimState 405 int1 = slotId 406 int2 = subId 407 }, 408 { "action $str1 state: $str2 slotId: $int1 subid: $int2" } 409 ) 410 } 411 412 fun logSimUnlocked(subId: Int) { 413 logBuffer.log(TAG, VERBOSE, { int1 = subId }, { "reportSimUnlocked(subId=$int1)" }) 414 } 415 416 fun logStartedListeningForFace(faceRunningState: Int, faceAuthUiEvent: FaceAuthUiEvent) { 417 logBuffer.log( 418 TAG, 419 VERBOSE, 420 { 421 int1 = faceRunningState 422 str1 = faceAuthUiEvent.reason 423 str2 = faceAuthUiEvent.extraInfoToString() 424 }, 425 { "startListeningForFace(): $int1, reason: $str1 $str2" } 426 ) 427 } 428 429 fun logStartedListeningForFaceFromWakeUp(faceRunningState: Int, @WakeReason pmWakeReason: Int) { 430 logBuffer.log( 431 TAG, 432 VERBOSE, 433 { 434 int1 = faceRunningState 435 str1 = PowerManager.wakeReasonToString(pmWakeReason) 436 }, 437 { "startListeningForFace(): $int1, reason: wakeUp-$str1" } 438 ) 439 } 440 441 fun logStoppedListeningForFace(faceRunningState: Int, faceAuthReason: String) { 442 logBuffer.log( 443 TAG, 444 VERBOSE, 445 { 446 int1 = faceRunningState 447 str1 = faceAuthReason 448 }, 449 { "stopListeningForFace(): currentFaceRunningState: $int1, reason: $str1" } 450 ) 451 } 452 453 fun logSubInfo(subInfo: SubscriptionInfo?) { 454 logBuffer.log(TAG, VERBOSE, { str1 = "$subInfo" }, { "SubInfo:$str1" }) 455 } 456 457 fun logTimeFormatChanged(newTimeFormat: String?) { 458 logBuffer.log( 459 TAG, 460 DEBUG, 461 { str1 = newTimeFormat }, 462 { "handleTimeFormatUpdate timeFormat=$str1" } 463 ) 464 } 465 fun logUdfpsPointerDown(sensorId: Int) { 466 logBuffer.log(TAG, DEBUG, { int1 = sensorId }, { "onUdfpsPointerDown, sensorId: $int1" }) 467 } 468 469 fun logUdfpsPointerUp(sensorId: Int) { 470 logBuffer.log(TAG, DEBUG, { int1 = sensorId }, { "onUdfpsPointerUp, sensorId: $int1" }) 471 } 472 473 fun logUnexpectedFaceCancellationSignalState(faceRunningState: Int, unlockPossible: Boolean) { 474 logBuffer.log( 475 TAG, 476 ERROR, 477 { 478 int1 = faceRunningState 479 bool1 = unlockPossible 480 }, 481 { 482 "Cancellation signal is not null, high chance of bug in " + 483 "face auth lifecycle management. " + 484 "Face state: $int1, unlockPossible: $bool1" 485 } 486 ) 487 } 488 489 fun logUnexpectedFpCancellationSignalState( 490 fingerprintRunningState: Int, 491 unlockPossible: Boolean 492 ) { 493 logBuffer.log( 494 TAG, 495 ERROR, 496 { 497 int1 = fingerprintRunningState 498 bool1 = unlockPossible 499 }, 500 { 501 "Cancellation signal is not null, high chance of bug in " + 502 "fp auth lifecycle management. FP state: $int1, unlockPossible: $bool1" 503 } 504 ) 505 } 506 507 fun logUnregisterCallback(callback: KeyguardUpdateMonitorCallback?) { 508 logBuffer.log(TAG, VERBOSE, { str1 = "$callback" }, { "*** unregister callback for $str1" }) 509 } 510 511 fun logUserRequestedUnlock( 512 requestOrigin: ActiveUnlockConfig.ActiveUnlockRequestOrigin, 513 reason: String?, 514 dismissKeyguard: Boolean 515 ) { 516 logBuffer.log( 517 "ActiveUnlock", 518 DEBUG, 519 { 520 str1 = requestOrigin?.name 521 str2 = reason 522 bool1 = dismissKeyguard 523 }, 524 { "reportUserRequestedUnlock origin=$str1 reason=$str2 dismissKeyguard=$bool1" } 525 ) 526 } 527 528 fun logTrustGrantedWithFlags( 529 flags: Int, 530 newlyUnlocked: Boolean, 531 userId: Int, 532 message: String? 533 ) { 534 logBuffer.log( 535 TAG, 536 DEBUG, 537 { 538 int1 = flags 539 bool1 = newlyUnlocked 540 int2 = userId 541 str1 = message 542 }, 543 { 544 "trustGrantedWithFlags[user=$int2] newlyUnlocked=$bool1 " + 545 "flags=${TrustGrantFlags(int1)} message=$str1" 546 } 547 ) 548 } 549 550 fun logTrustChanged(wasTrusted: Boolean, isNowTrusted: Boolean, userId: Int) { 551 logBuffer.log( 552 TAG, 553 DEBUG, 554 { 555 bool1 = wasTrusted 556 bool2 = isNowTrusted 557 int1 = userId 558 }, 559 { "onTrustChanged[user=$int1] wasTrusted=$bool1 isNowTrusted=$bool2" } 560 ) 561 } 562 563 fun logKeyguardStateUpdate( 564 secure: Boolean, 565 canDismissLockScreen: Boolean, 566 trusted: Boolean, 567 trustManaged: Boolean 568 ) { 569 logBuffer.log( 570 "KeyguardState", 571 DEBUG, 572 { 573 bool1 = secure 574 bool2 = canDismissLockScreen 575 bool3 = trusted 576 bool4 = trustManaged 577 }, 578 { 579 "#update secure=$bool1 canDismissKeyguard=$bool2" + 580 " trusted=$bool3 trustManaged=$bool4" 581 } 582 ) 583 } 584 585 fun logSkipUpdateFaceListeningOnWakeup(@WakeReason pmWakeReason: Int) { 586 logBuffer.log( 587 TAG, 588 VERBOSE, 589 { str1 = PowerManager.wakeReasonToString(pmWakeReason) }, 590 { "Skip updating face listening state on wakeup from $str1" } 591 ) 592 } 593 594 fun logTaskStackChangedForAssistant(assistantVisible: Boolean) { 595 logBuffer.log( 596 TAG, 597 VERBOSE, 598 { bool1 = assistantVisible }, 599 { "TaskStackChanged for ACTIVITY_TYPE_ASSISTANT, assistant visible: $bool1" } 600 ) 601 } 602 603 fun allowFingerprintOnCurrentOccludingActivityChanged(allow: Boolean) { 604 logBuffer.log( 605 TAG, 606 VERBOSE, 607 { bool1 = allow }, 608 { "allowFingerprintOnCurrentOccludingActivityChanged: $bool1" } 609 ) 610 } 611 612 fun logAssistantVisible(assistantVisible: Boolean) { 613 logBuffer.log( 614 TAG, 615 VERBOSE, 616 { bool1 = assistantVisible }, 617 { "Updating mAssistantVisible to new value: $bool1" } 618 ) 619 } 620 621 fun logReportSuccessfulBiometricUnlock(isStrongBiometric: Boolean, userId: Int) { 622 logBuffer.log( 623 TAG, 624 DEBUG, 625 { 626 bool1 = isStrongBiometric 627 int1 = userId 628 }, 629 { "reporting successful biometric unlock: isStrongBiometric: $bool1, userId: $int1" } 630 ) 631 } 632 633 fun logHandlerHasAuthContinueMsgs(action: Int) { 634 logBuffer.log( 635 TAG, 636 DEBUG, 637 { int1 = action }, 638 { 639 "MSG_BIOMETRIC_AUTHENTICATION_CONTINUE already queued up, " + 640 "ignoring updating FP listening state to $int1" 641 } 642 ) 643 } 644 645 fun logFaceEnrolledUpdated(oldValue: Boolean, newValue: Boolean) { 646 logBuffer.log( 647 TAG, 648 DEBUG, 649 { 650 bool1 = oldValue 651 bool2 = newValue 652 }, 653 { "Face enrolled state changed: old: $bool1, new: $bool2" } 654 ) 655 } 656 657 fun logFpEnrolledUpdated(userId: Int, oldValue: Boolean, newValue: Boolean) { 658 logBuffer.log( 659 TAG, 660 DEBUG, 661 { 662 int1 = userId 663 bool1 = oldValue 664 bool2 = newValue 665 }, 666 { "Fp enrolled state changed for userId: $int1 old: $bool1, new: $bool2" } 667 ) 668 } 669 670 fun logTrustUsuallyManagedUpdated( 671 userId: Int, 672 oldValue: Boolean, 673 newValue: Boolean, 674 context: String 675 ) { 676 logBuffer.log( 677 TAG, 678 DEBUG, 679 { 680 int1 = userId 681 bool1 = oldValue 682 bool2 = newValue 683 str1 = context 684 }, 685 { 686 "trustUsuallyManaged changed for " + 687 "userId: $int1 " + 688 "old: $bool1, " + 689 "new: $bool2 " + 690 "context: $context" 691 } 692 ) 693 } 694 695 fun logHandleBatteryUpdate(batteryStatus: BatteryStatus?) { 696 logBuffer.log( 697 TAG, 698 DEBUG, 699 { 700 bool1 = batteryStatus != null 701 int1 = batteryStatus?.status ?: -1 702 int2 = batteryStatus?.chargingStatus ?: -1 703 long1 = (batteryStatus?.level ?: -1).toLong() 704 long2 = (batteryStatus?.maxChargingWattage ?: -1).toLong() 705 str1 = "${batteryStatus?.plugged ?: -1}" 706 }, 707 { 708 "handleBatteryUpdate: isNotNull: $bool1 " + 709 "BatteryStatus{status= $int1, " + 710 "level=$long1, " + 711 "plugged=$str1, " + 712 "chargingStatus=$int2, " + 713 "maxChargingWattage= $long2}" 714 } 715 ) 716 } 717 718 fun scheduleWatchdog(@CompileTimeConstant watchdogType: String) { 719 logBuffer.log(TAG, DEBUG, "Scheduling biometric watchdog for $watchdogType") 720 } 721 722 fun notifyAboutEnrollmentsChanged(biometricSourceType: BiometricSourceType) { 723 logBuffer.log( 724 TAG, 725 DEBUG, 726 { str1 = "$biometricSourceType" }, 727 { "notifying about enrollments changed: $str1" } 728 ) 729 } 730 731 fun logUserSwitching(userId: Int, context: String) { 732 logBuffer.log( 733 TAG, 734 DEBUG, 735 { 736 int1 = userId 737 str1 = context 738 }, 739 { "userCurrentlySwitching: $str1, userId: $int1" } 740 ) 741 } 742 743 fun logUserSwitchComplete(userId: Int, context: String) { 744 logBuffer.log( 745 TAG, 746 DEBUG, 747 { 748 int1 = userId 749 str1 = context 750 }, 751 { "userSwitchComplete: $str1, userId: $int1" } 752 ) 753 } 754 } 755