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