• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.hardware.biometrics.BiometricConstants.LockoutMode
20 import android.os.PowerManager
21 import android.os.PowerManager.WakeReason
22 import android.telephony.ServiceState
23 import android.telephony.SubscriptionInfo
24 import com.android.keyguard.ActiveUnlockConfig
25 import com.android.keyguard.FaceAuthUiEvent
26 import com.android.keyguard.KeyguardListenModel
27 import com.android.keyguard.KeyguardUpdateMonitorCallback
28 import com.android.keyguard.TrustGrantFlags
29 import com.android.systemui.log.dagger.KeyguardUpdateMonitorLog
30 import com.android.systemui.plugins.log.LogBuffer
31 import com.android.systemui.plugins.log.LogLevel
32 import com.android.systemui.plugins.log.LogLevel.DEBUG
33 import com.android.systemui.plugins.log.LogLevel.ERROR
34 import com.android.systemui.plugins.log.LogLevel.INFO
35 import com.android.systemui.plugins.log.LogLevel.VERBOSE
36 import com.android.systemui.plugins.log.LogLevel.WARNING
37 import com.google.errorprone.annotations.CompileTimeConstant
38 import javax.inject.Inject
39 
40 private const val TAG = "KeyguardUpdateMonitorLog"
41 
42 /** Helper class for logging for [com.android.keyguard.KeyguardUpdateMonitor] */
43 class KeyguardUpdateMonitorLogger
44 @Inject
45 constructor(@KeyguardUpdateMonitorLog private val logBuffer: LogBuffer) {
dnull46     fun d(@CompileTimeConstant msg: String) = log(msg, DEBUG)
47 
48     fun e(@CompileTimeConstant msg: String) = log(msg, ERROR)
49 
50     fun v(@CompileTimeConstant msg: String) = log(msg, VERBOSE)
51 
52     fun w(@CompileTimeConstant msg: String) = log(msg, WARNING)
53 
54     fun log(@CompileTimeConstant msg: String, level: LogLevel) = logBuffer.log(TAG, level, msg)
55 
56     fun logActiveUnlockTriggered(reason: String?) {
57         logBuffer.log(
58             "ActiveUnlock",
59             DEBUG,
60             { str1 = reason },
61             { "initiate active unlock triggerReason=$str1" }
62         )
63     }
64 
logActiveUnlockRequestSkippedForWakeReasonDueToFaceConfignull65     fun logActiveUnlockRequestSkippedForWakeReasonDueToFaceConfig(wakeReason: Int) {
66         logBuffer.log(
67             "ActiveUnlock",
68             DEBUG,
69             { int1 = wakeReason },
70             { "Skip requesting active unlock from wake reason that doesn't trigger face auth" +
71                     " reason=${PowerManager.wakeReasonToString(int1)}" }
72         )
73     }
74 
logAuthInterruptDetectednull75     fun logAuthInterruptDetected(active: Boolean) {
76         logBuffer.log(TAG, DEBUG, { bool1 = active }, { "onAuthInterruptDetected($bool1)" })
77     }
78 
logBroadcastReceivednull79     fun logBroadcastReceived(action: String?) {
80         logBuffer.log(TAG, DEBUG, { str1 = action }, { "received broadcast $str1" })
81     }
82 
logDeviceProvisionedStatenull83     fun logDeviceProvisionedState(deviceProvisioned: Boolean) {
84         logBuffer.log(
85             TAG,
86             DEBUG,
87             { bool1 = deviceProvisioned },
88             { "DEVICE_PROVISIONED state = $bool1" }
89         )
90     }
91 
logExceptionnull92     fun logException(ex: Exception, @CompileTimeConstant logMsg: String) {
93         logBuffer.log(TAG, ERROR, {}, { logMsg }, exception = ex)
94     }
95 
logFaceAcquirednull96     fun logFaceAcquired(acquireInfo: Int) {
97         logBuffer.log(TAG, DEBUG, { int1 = acquireInfo }, { "Face acquired acquireInfo=$int1" })
98     }
99 
logFaceAuthDisabledForUsernull100     fun logFaceAuthDisabledForUser(userId: Int) {
101         logBuffer.log(
102             TAG,
103             DEBUG,
104             { int1 = userId },
105             { "Face authentication disabled by DPM for userId: $int1" }
106         )
107     }
logFaceAuthErrornull108     fun logFaceAuthError(msgId: Int, originalErrMsg: String) {
109         logBuffer.log(
110             TAG,
111             DEBUG,
112             {
113                 str1 = originalErrMsg
114                 int1 = msgId
115             },
116             { "Face error received: $str1 msgId= $int1" }
117         )
118     }
119 
logFaceAuthForWrongUsernull120     fun logFaceAuthForWrongUser(authUserId: Int) {
121         logBuffer.log(
122             TAG,
123             DEBUG,
124             { int1 = authUserId },
125             { "Face authenticated for wrong user: $int1" }
126         )
127     }
128 
logFaceAuthHelpMsgnull129     fun logFaceAuthHelpMsg(msgId: Int, helpMsg: String?) {
130         logBuffer.log(
131             TAG,
132             DEBUG,
133             {
134                 int1 = msgId
135                 str1 = helpMsg
136             },
137             { "Face help received, msgId: $int1 msg: $str1" }
138         )
139     }
140 
logFaceAuthRequestednull141     fun logFaceAuthRequested(reason: String?) {
142         logBuffer.log(TAG, DEBUG, { str1 = reason }, { "requestFaceAuth() reason=$str1" })
143     }
144 
logFaceAuthSuccessnull145     fun logFaceAuthSuccess(userId: Int) {
146         logBuffer.log(TAG, DEBUG, { int1 = userId }, { "Face auth succeeded for user $int1" })
147     }
148 
logFaceLockoutResetnull149     fun logFaceLockoutReset(@LockoutMode mode: Int) {
150         logBuffer.log(TAG, DEBUG, { int1 = mode }, { "handleFaceLockoutReset: $int1" })
151     }
152 
logFaceRunningStatenull153     fun logFaceRunningState(faceRunningState: Int) {
154         logBuffer.log(TAG, DEBUG, { int1 = faceRunningState }, { "faceRunningState: $int1" })
155     }
156 
logFaceUnlockPossiblenull157     fun logFaceUnlockPossible(isFaceUnlockPossible: Boolean) {
158         logBuffer.log(
159             TAG,
160             DEBUG,
161             { bool1 = isFaceUnlockPossible },
162             { "isUnlockWithFacePossible: $bool1" }
163         )
164     }
165 
logFingerprintAuthForWrongUsernull166     fun logFingerprintAuthForWrongUser(authUserId: Int) {
167         logBuffer.log(
168             TAG,
169             DEBUG,
170             { int1 = authUserId },
171             { "Fingerprint authenticated for wrong user: $int1" }
172         )
173     }
174 
logFingerprintDisabledForUsernull175     fun logFingerprintDisabledForUser(userId: Int) {
176         logBuffer.log(
177             TAG,
178             DEBUG,
179             { int1 = userId },
180             { "Fingerprint disabled by DPM for userId: $int1" }
181         )
182     }
183 
logFingerprintLockoutResetnull184     fun logFingerprintLockoutReset(@LockoutMode mode: Int) {
185         logBuffer.log(TAG, DEBUG, { int1 = mode }, { "handleFingerprintLockoutReset: $int1" })
186     }
187 
logFingerprintRunningStatenull188     fun logFingerprintRunningState(fingerprintRunningState: Int) {
189         logBuffer.log(
190             TAG,
191             DEBUG,
192             { int1 = fingerprintRunningState },
193             { "fingerprintRunningState: $int1" }
194         )
195     }
196 
logFingerprintSuccessnull197     fun logFingerprintSuccess(userId: Int, isStrongBiometric: Boolean) {
198         logBuffer.log(
199             TAG,
200             DEBUG,
201             {
202                 int1 = userId
203                 bool1 = isStrongBiometric
204             },
205             { "Fingerprint auth successful: userId: $int1, isStrongBiometric: $bool1" }
206         )
207     }
208 
logFaceDetectednull209     fun logFaceDetected(userId: Int, isStrongBiometric: Boolean) {
210         logBuffer.log(TAG, DEBUG, {
211             int1 = userId
212             bool1 = isStrongBiometric
213         }, {"Face detected: userId: $int1, isStrongBiometric: $bool1"})
214     }
215 
logFingerprintDetectednull216     fun logFingerprintDetected(userId: Int, isStrongBiometric: Boolean) {
217         logBuffer.log(TAG, DEBUG, {
218             int1 = userId
219             bool1 = isStrongBiometric
220         }, {"Fingerprint detected: userId: $int1, isStrongBiometric: $bool1"})
221     }
222 
logFingerprintErrornull223     fun logFingerprintError(msgId: Int, originalErrMsg: String) {
224         logBuffer.log(
225             TAG,
226             DEBUG,
227             {
228                 str1 = originalErrMsg
229                 int1 = msgId
230             },
231             { "Fingerprint error received: $str1 msgId= $int1" }
232         )
233     }
234 
logInvalidSubIdnull235     fun logInvalidSubId(subId: Int) {
236         logBuffer.log(
237             TAG,
238             INFO,
239             { int1 = subId },
240             { "Previously active sub id $int1 is now invalid, will remove" }
241         )
242     }
243 
logPrimaryKeyguardBouncerChangednull244     fun logPrimaryKeyguardBouncerChanged(
245         primaryBouncerIsOrWillBeShowing: Boolean,
246         primaryBouncerFullyShown: Boolean
247     ) {
248         logBuffer.log(
249             TAG,
250             DEBUG,
251             {
252                 bool1 = primaryBouncerIsOrWillBeShowing
253                 bool2 = primaryBouncerFullyShown
254             },
255             {
256                 "handlePrimaryBouncerChanged " +
257                     "primaryBouncerIsOrWillBeShowing=$bool1 primaryBouncerFullyShown=$bool2"
258             }
259         )
260     }
261 
logKeyguardListenerModelnull262     fun logKeyguardListenerModel(model: KeyguardListenModel) {
263         logBuffer.log(TAG, VERBOSE, { str1 = "$model" }, { str1!! })
264     }
265 
logKeyguardShowingChangednull266     fun logKeyguardShowingChanged(showing: Boolean, occluded: Boolean, visible: Boolean) {
267         logBuffer.log(
268             TAG,
269             DEBUG,
270             {
271                 bool1 = showing
272                 bool2 = occluded
273                 bool3 = visible
274             },
275             { "keyguardShowingChanged(showing=$bool1 occluded=$bool2 visible=$bool3)" }
276         )
277     }
278 
logMissingSupervisorAppErrornull279     fun logMissingSupervisorAppError(userId: Int) {
280         logBuffer.log(
281             TAG,
282             ERROR,
283             { int1 = userId },
284             { "No Profile Owner or Device Owner supervision app found for User $int1" }
285         )
286     }
287 
logPhoneStateChangednull288     fun logPhoneStateChanged(newState: String?) {
289         logBuffer.log(TAG, DEBUG, { str1 = newState }, { "handlePhoneStateChanged($str1)" })
290     }
291 
logRegisterCallbacknull292     fun logRegisterCallback(callback: KeyguardUpdateMonitorCallback?) {
293         logBuffer.log(TAG, VERBOSE, { str1 = "$callback" }, { "*** register callback for $str1" })
294     }
295 
logRetryingAfterFaceHwUnavailablenull296     fun logRetryingAfterFaceHwUnavailable(retryCount: Int) {
297         logBuffer.log(
298             TAG,
299             WARNING,
300             { int1 = retryCount },
301             { "Retrying face after HW unavailable, attempt $int1" }
302         )
303     }
304 
logRetryAfterFpErrorWithDelaynull305     fun logRetryAfterFpErrorWithDelay(msgId: Int, errString: String?, delay: Int) {
306         logBuffer.log(
307             TAG,
308             DEBUG,
309             {
310                 int1 = msgId
311                 int2 = delay
312                 str1 = "$errString"
313             },
314             { "Fingerprint scheduling retry auth after $int2 ms due to($int1) -> $str1" }
315         )
316     }
317 
logRetryAfterFpHwUnavailablenull318     fun logRetryAfterFpHwUnavailable(retryCount: Int) {
319         logBuffer.log(
320             TAG,
321             WARNING,
322             { int1 = retryCount },
323             { "Retrying fingerprint attempt: $int1" }
324         )
325     }
326 
logSendPrimaryBouncerChangednull327     fun logSendPrimaryBouncerChanged(
328         primaryBouncerIsOrWillBeShowing: Boolean,
329         primaryBouncerFullyShown: Boolean,
330     ) {
331         logBuffer.log(
332             TAG,
333             DEBUG,
334             {
335                 bool1 = primaryBouncerIsOrWillBeShowing
336                 bool2 = primaryBouncerFullyShown
337             },
338             {
339                 "sendPrimaryBouncerChanged primaryBouncerIsOrWillBeShowing=$bool1 " +
340                     "primaryBouncerFullyShown=$bool2"
341             }
342         )
343     }
344 
logServiceStateChangenull345     fun logServiceStateChange(subId: Int, serviceState: ServiceState?) {
346         logBuffer.log(
347             TAG,
348             DEBUG,
349             {
350                 int1 = subId
351                 str1 = "$serviceState"
352             },
353             { "handleServiceStateChange(subId=$int1, serviceState=$str1)" }
354         )
355     }
356 
logServiceStateIntentnull357     fun logServiceStateIntent(action: String?, serviceState: ServiceState?, subId: Int) {
358         logBuffer.log(
359             TAG,
360             VERBOSE,
361             {
362                 str1 = action
363                 str2 = "$serviceState"
364                 int1 = subId
365             },
366             { "action $str1 serviceState=$str2 subId=$int1" }
367         )
368     }
369 
logSimStatenull370     fun logSimState(subId: Int, slotId: Int, state: Int) {
371         logBuffer.log(
372             TAG,
373             DEBUG,
374             {
375                 int1 = subId
376                 int2 = slotId
377                 long1 = state.toLong()
378             },
379             { "handleSimStateChange(subId=$int1, slotId=$int2, state=$long1)" }
380         )
381     }
382 
logSimStateFromIntentnull383     fun logSimStateFromIntent(action: String?, extraSimState: String?, slotId: Int, subId: Int) {
384         logBuffer.log(
385             TAG,
386             VERBOSE,
387             {
388                 str1 = action
389                 str2 = extraSimState
390                 int1 = slotId
391                 int2 = subId
392             },
393             { "action $str1 state: $str2 slotId: $int1 subid: $int2" }
394         )
395     }
396 
logSimUnlockednull397     fun logSimUnlocked(subId: Int) {
398         logBuffer.log(TAG, VERBOSE, { int1 = subId }, { "reportSimUnlocked(subId=$int1)" })
399     }
400 
logStartedListeningForFacenull401     fun logStartedListeningForFace(faceRunningState: Int, faceAuthUiEvent: FaceAuthUiEvent) {
402         logBuffer.log(
403             TAG,
404             VERBOSE,
405             {
406                 int1 = faceRunningState
407                 str1 = faceAuthUiEvent.reason
408                 str2 = faceAuthUiEvent.extraInfoToString()
409             },
410             { "startListeningForFace(): $int1, reason: $str1 $str2" }
411         )
412     }
413 
logStartedListeningForFaceFromWakeUpnull414     fun logStartedListeningForFaceFromWakeUp(faceRunningState: Int, @WakeReason pmWakeReason: Int) {
415         logBuffer.log(
416             TAG,
417             VERBOSE,
418             {
419                 int1 = faceRunningState
420                 str1 = PowerManager.wakeReasonToString(pmWakeReason)
421             },
422             { "startListeningForFace(): $int1, reason: wakeUp-$str1" }
423         )
424     }
425 
logStoppedListeningForFacenull426     fun logStoppedListeningForFace(faceRunningState: Int, faceAuthReason: String) {
427         logBuffer.log(
428             TAG,
429             VERBOSE,
430             {
431                 int1 = faceRunningState
432                 str1 = faceAuthReason
433             },
434             { "stopListeningForFace(): currentFaceRunningState: $int1, reason: $str1" }
435         )
436     }
437 
logSubInfonull438     fun logSubInfo(subInfo: SubscriptionInfo?) {
439         logBuffer.log(TAG, VERBOSE, { str1 = "$subInfo" }, { "SubInfo:$str1" })
440     }
441 
logTimeFormatChangednull442     fun logTimeFormatChanged(newTimeFormat: String?) {
443         logBuffer.log(
444             TAG,
445             DEBUG,
446             { str1 = newTimeFormat },
447             { "handleTimeFormatUpdate timeFormat=$str1" }
448         )
449     }
logUdfpsPointerDownnull450     fun logUdfpsPointerDown(sensorId: Int) {
451         logBuffer.log(TAG, DEBUG, { int1 = sensorId }, { "onUdfpsPointerDown, sensorId: $int1" })
452     }
453 
logUdfpsPointerUpnull454     fun logUdfpsPointerUp(sensorId: Int) {
455         logBuffer.log(TAG, DEBUG, { int1 = sensorId }, { "onUdfpsPointerUp, sensorId: $int1" })
456     }
457 
logUnexpectedFaceCancellationSignalStatenull458     fun logUnexpectedFaceCancellationSignalState(faceRunningState: Int, unlockPossible: Boolean) {
459         logBuffer.log(
460             TAG,
461             ERROR,
462             {
463                 int1 = faceRunningState
464                 bool1 = unlockPossible
465             },
466             {
467                 "Cancellation signal is not null, high chance of bug in " +
468                     "face auth lifecycle management. " +
469                     "Face state: $int1, unlockPossible: $bool1"
470             }
471         )
472     }
473 
logUnexpectedFpCancellationSignalStatenull474     fun logUnexpectedFpCancellationSignalState(
475         fingerprintRunningState: Int,
476         unlockPossible: Boolean
477     ) {
478         logBuffer.log(
479             TAG,
480             ERROR,
481             {
482                 int1 = fingerprintRunningState
483                 bool1 = unlockPossible
484             },
485             {
486                 "Cancellation signal is not null, high chance of bug in " +
487                     "fp auth lifecycle management. FP state: $int1, unlockPossible: $bool1"
488             }
489         )
490     }
491 
logUnregisterCallbacknull492     fun logUnregisterCallback(callback: KeyguardUpdateMonitorCallback?) {
493         logBuffer.log(TAG, VERBOSE, { str1 = "$callback" }, { "*** unregister callback for $str1" })
494     }
495 
logUserRequestedUnlocknull496     fun logUserRequestedUnlock(
497         requestOrigin: ActiveUnlockConfig.ActiveUnlockRequestOrigin,
498         reason: String?,
499         dismissKeyguard: Boolean
500     ) {
501         logBuffer.log(
502             "ActiveUnlock",
503             DEBUG,
504             {
505                 str1 = requestOrigin?.name
506                 str2 = reason
507                 bool1 = dismissKeyguard
508             },
509             { "reportUserRequestedUnlock origin=$str1 reason=$str2 dismissKeyguard=$bool1" }
510         )
511     }
512 
logTrustGrantedWithFlagsnull513     fun logTrustGrantedWithFlags(
514         flags: Int,
515         newlyUnlocked: Boolean,
516         userId: Int,
517         message: String?
518     ) {
519         logBuffer.log(
520             TAG,
521             DEBUG,
522             {
523                 int1 = flags
524                 bool1 = newlyUnlocked
525                 int2 = userId
526                 str1 = message
527             },
528             {
529                 "trustGrantedWithFlags[user=$int2] newlyUnlocked=$bool1 " +
530                     "flags=${TrustGrantFlags(int1)} message=$str1"
531             }
532         )
533     }
534 
logTrustChangednull535     fun logTrustChanged(wasTrusted: Boolean, isNowTrusted: Boolean, userId: Int) {
536         logBuffer.log(
537             TAG,
538             DEBUG,
539             {
540                 bool1 = wasTrusted
541                 bool2 = isNowTrusted
542                 int1 = userId
543             },
544             { "onTrustChanged[user=$int1] wasTrusted=$bool1 isNowTrusted=$bool2" }
545         )
546     }
547 
logKeyguardStateUpdatenull548     fun logKeyguardStateUpdate(
549         secure: Boolean,
550         canDismissLockScreen: Boolean,
551         trusted: Boolean,
552         trustManaged: Boolean
553     ) {
554         logBuffer.log(
555             "KeyguardState",
556             DEBUG,
557             {
558                 bool1 = secure
559                 bool2 = canDismissLockScreen
560                 bool3 = trusted
561                 bool4 = trustManaged
562             },
563             {
564                 "#update secure=$bool1 canDismissKeyguard=$bool2" +
565                     " trusted=$bool3 trustManaged=$bool4"
566             }
567         )
568     }
569 
logSkipUpdateFaceListeningOnWakeupnull570     fun logSkipUpdateFaceListeningOnWakeup(@WakeReason pmWakeReason: Int) {
571         logBuffer.log(
572             TAG,
573             VERBOSE,
574             { str1 = PowerManager.wakeReasonToString(pmWakeReason) },
575             { "Skip updating face listening state on wakeup from $str1" }
576         )
577     }
578 
logTaskStackChangedForAssistantnull579     fun logTaskStackChangedForAssistant(assistantVisible: Boolean) {
580         logBuffer.log(
581             TAG,
582             VERBOSE,
583             { bool1 = assistantVisible },
584             { "TaskStackChanged for ACTIVITY_TYPE_ASSISTANT, assistant visible: $bool1" }
585         )
586     }
587 
logAssistantVisiblenull588     fun logAssistantVisible(assistantVisible: Boolean) {
589         logBuffer.log(
590             TAG,
591             VERBOSE,
592             { bool1 = assistantVisible },
593             { "Updating mAssistantVisible to new value: $bool1" }
594         )
595     }
596 
logReportSuccessfulBiometricUnlocknull597     fun logReportSuccessfulBiometricUnlock(isStrongBiometric: Boolean, userId: Int) {
598         logBuffer.log(
599             TAG,
600             DEBUG,
601             {
602                 bool1 = isStrongBiometric
603                 int1 = userId
604             },
605             { "reporting successful biometric unlock: isStrongBiometric: $bool1, userId: $int1" }
606         )
607     }
608 
logHandlerHasAuthContinueMsgsnull609     fun logHandlerHasAuthContinueMsgs(action: Int) {
610         logBuffer.log(
611             TAG,
612             DEBUG,
613             { int1 = action },
614             {
615                 "MSG_BIOMETRIC_AUTHENTICATION_CONTINUE already queued up, " +
616                     "ignoring updating FP listening state to $int1"
617             }
618         )
619     }
620 
logFaceEnrolledUpdatednull621     fun logFaceEnrolledUpdated(oldValue: Boolean, newValue: Boolean) {
622         logBuffer.log(
623             TAG,
624             DEBUG,
625             {
626                 bool1 = oldValue
627                 bool2 = newValue
628             },
629             { "Face enrolled state changed: old: $bool1, new: $bool2" }
630         )
631     }
632 
logFpEnrolledUpdatednull633     fun logFpEnrolledUpdated(userId: Int, oldValue: Boolean, newValue: Boolean) {
634         logBuffer.log(
635             TAG,
636             DEBUG,
637             {
638                 int1 = userId
639                 bool1 = oldValue
640                 bool2 = newValue
641             },
642             { "Fp enrolled state changed for userId: $int1 old: $bool1, new: $bool2" }
643         )
644     }
645 
logTrustUsuallyManagedUpdatednull646     fun logTrustUsuallyManagedUpdated(
647         userId: Int,
648         oldValue: Boolean,
649         newValue: Boolean,
650         context: String
651     ) {
652         logBuffer.log(
653             TAG,
654             DEBUG,
655             {
656                 int1 = userId
657                 bool1 = oldValue
658                 bool2 = newValue
659                 str1 = context
660             },
661             {
662                 "trustUsuallyManaged changed for " +
663                     "userId: $int1 " +
664                     "old: $bool1, " +
665                     "new: $bool2 " +
666                     "context: $context"
667             }
668         )
669     }
670 
logHandleBatteryUpdatenull671     fun logHandleBatteryUpdate(isInteresting: Boolean) {
672         logBuffer.log(
673             TAG,
674             DEBUG,
675             {
676                 bool1 = isInteresting
677             },
678             { "handleBatteryUpdate: $bool1" }
679         )
680     }
681 }
682