Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f4df5bc2 authored by Beverly Tai's avatar Beverly Tai Committed by Android (Google) Code Review
Browse files

Merge "Gate & metrics log WakeReason for face auth run" into tm-qpr-dev

parents 268f0020 897dcdb8
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -643,6 +643,18 @@
        <item>26</item> <!-- MOUTH_COVERING_DETECTED -->
    </integer-array>

    <!-- Which device wake-ups will trigger face auth. These values correspond with
         PowerManager#WakeReason. -->
    <integer-array name="config_face_auth_wake_up_triggers">
        <item>1</item> <!-- WAKE_REASON_POWER_BUTTON -->
        <item>4</item> <!-- WAKE_REASON_GESTURE -->
        <item>6</item> <!-- WAKE_REASON_WAKE_KEY -->
        <item>7</item> <!-- WAKE_REASON_WAKE_MOTION -->
        <item>9</item> <!-- WAKE_REASON_LID -->
        <item>10</item> <!-- WAKE_REASON_DISPLAY_GROUP_ADDED -->
        <item>12</item> <!-- WAKE_REASON_UNFOLD_DEVICE -->
    </integer-array>

    <!-- Whether the communal service should be enabled -->
    <bool name="config_communalServiceEnabled">false</bool>

+34 −62
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.keyguard

import android.annotation.StringDef
import android.os.PowerManager
import com.android.internal.logging.UiEvent
import com.android.internal.logging.UiEventLogger
import com.android.keyguard.FaceAuthApiRequestReason.Companion.NOTIFICATION_PANEL_CLICKED
@@ -122,122 +123,93 @@ private object InternalFaceAuthReasons {
        "Face auth started/stopped because biometric is enabled on keyguard"
}

/** UiEvents that are logged to identify why face auth is being triggered. */
enum class FaceAuthUiEvent constructor(private val id: Int, val reason: String) :
/**
 * UiEvents that are logged to identify why face auth is being triggered.
 * @param extraInfo is logged as the position. See [UiEventLogger#logWithInstanceIdAndPosition]
 */
enum class FaceAuthUiEvent
constructor(private val id: Int, val reason: String, var extraInfo: Int = 0) :
    UiEventLogger.UiEventEnum {
    @UiEvent(doc = OCCLUDING_APP_REQUESTED)
    FACE_AUTH_TRIGGERED_OCCLUDING_APP_REQUESTED(1146, OCCLUDING_APP_REQUESTED),

    @UiEvent(doc = UDFPS_POINTER_DOWN)
    FACE_AUTH_TRIGGERED_UDFPS_POINTER_DOWN(1147, UDFPS_POINTER_DOWN),

    @UiEvent(doc = SWIPE_UP_ON_BOUNCER)
    FACE_AUTH_TRIGGERED_SWIPE_UP_ON_BOUNCER(1148, SWIPE_UP_ON_BOUNCER),

    @UiEvent(doc = DEVICE_WOKEN_UP_ON_REACH_GESTURE)
    FACE_AUTH_TRIGGERED_ON_REACH_GESTURE_ON_AOD(1149, DEVICE_WOKEN_UP_ON_REACH_GESTURE),

    @UiEvent(doc = FACE_LOCKOUT_RESET)
    FACE_AUTH_TRIGGERED_FACE_LOCKOUT_RESET(1150, FACE_LOCKOUT_RESET),

    @UiEvent(doc = QS_EXPANDED)
    FACE_AUTH_TRIGGERED_QS_EXPANDED(1151, QS_EXPANDED),

    @UiEvent(doc = QS_EXPANDED) FACE_AUTH_TRIGGERED_QS_EXPANDED(1151, QS_EXPANDED),
    @UiEvent(doc = NOTIFICATION_PANEL_CLICKED)
    FACE_AUTH_TRIGGERED_NOTIFICATION_PANEL_CLICKED(1152, NOTIFICATION_PANEL_CLICKED),

    @UiEvent(doc = PICK_UP_GESTURE_TRIGGERED)
    FACE_AUTH_TRIGGERED_PICK_UP_GESTURE_TRIGGERED(1153, PICK_UP_GESTURE_TRIGGERED),

    @UiEvent(doc = ALTERNATE_BIOMETRIC_BOUNCER_SHOWN)
    FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN(1154,
        ALTERNATE_BIOMETRIC_BOUNCER_SHOWN),

    FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN(1154, ALTERNATE_BIOMETRIC_BOUNCER_SHOWN),
    @UiEvent(doc = PRIMARY_BOUNCER_SHOWN)
    FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN(1155, PRIMARY_BOUNCER_SHOWN),

    @UiEvent(doc = PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN)
    FACE_AUTH_UPDATED_PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN(
        1197,
        PRIMARY_BOUNCER_SHOWN_OR_WILL_BE_SHOWN
    ),

    @UiEvent(doc = RETRY_AFTER_HW_UNAVAILABLE)
    FACE_AUTH_TRIGGERED_RETRY_AFTER_HW_UNAVAILABLE(1156, RETRY_AFTER_HW_UNAVAILABLE),

    @UiEvent(doc = TRUST_DISABLED)
    FACE_AUTH_TRIGGERED_TRUST_DISABLED(1158, TRUST_DISABLED),

    @UiEvent(doc = TRUST_ENABLED)
    FACE_AUTH_STOPPED_TRUST_ENABLED(1173, TRUST_ENABLED),

    @UiEvent(doc = TRUST_DISABLED) FACE_AUTH_TRIGGERED_TRUST_DISABLED(1158, TRUST_DISABLED),
    @UiEvent(doc = TRUST_ENABLED) FACE_AUTH_STOPPED_TRUST_ENABLED(1173, TRUST_ENABLED),
    @UiEvent(doc = KEYGUARD_OCCLUSION_CHANGED)
    FACE_AUTH_UPDATED_KEYGUARD_OCCLUSION_CHANGED(1159, KEYGUARD_OCCLUSION_CHANGED),

    @UiEvent(doc = ASSISTANT_VISIBILITY_CHANGED)
    FACE_AUTH_UPDATED_ASSISTANT_VISIBILITY_CHANGED(1160, ASSISTANT_VISIBILITY_CHANGED),

    @UiEvent(doc = STARTED_WAKING_UP)
    FACE_AUTH_UPDATED_STARTED_WAKING_UP(1161, STARTED_WAKING_UP),

    FACE_AUTH_UPDATED_STARTED_WAKING_UP(1161, STARTED_WAKING_UP) {
        override fun extraInfoToString(): String {
            return PowerManager.wakeReasonToString(extraInfo)
        }
    },
    @Deprecated(
        "Not a face auth trigger.",
        ReplaceWith(
            "FACE_AUTH_UPDATED_STARTED_WAKING_UP, " +
                "extraInfo=PowerManager.WAKE_REASON_DREAM_FINISHED"
        )
    )
    @UiEvent(doc = DREAM_STOPPED)
    FACE_AUTH_TRIGGERED_DREAM_STOPPED(1162, DREAM_STOPPED),

    @UiEvent(doc = ALL_AUTHENTICATORS_REGISTERED)
    FACE_AUTH_TRIGGERED_ALL_AUTHENTICATORS_REGISTERED(1163, ALL_AUTHENTICATORS_REGISTERED),

    @UiEvent(doc = ENROLLMENTS_CHANGED)
    FACE_AUTH_TRIGGERED_ENROLLMENTS_CHANGED(1164, ENROLLMENTS_CHANGED),

    @UiEvent(doc = KEYGUARD_VISIBILITY_CHANGED)
    FACE_AUTH_UPDATED_KEYGUARD_VISIBILITY_CHANGED(1165, KEYGUARD_VISIBILITY_CHANGED),

    @UiEvent(doc = FACE_CANCEL_NOT_RECEIVED)
    FACE_AUTH_STOPPED_FACE_CANCEL_NOT_RECEIVED(1174, FACE_CANCEL_NOT_RECEIVED),

    @UiEvent(doc = AUTH_REQUEST_DURING_CANCELLATION)
    FACE_AUTH_TRIGGERED_DURING_CANCELLATION(1175, AUTH_REQUEST_DURING_CANCELLATION),

    @UiEvent(doc = DREAM_STARTED)
    FACE_AUTH_STOPPED_DREAM_STARTED(1176, DREAM_STARTED),

    @UiEvent(doc = FP_LOCKED_OUT)
    FACE_AUTH_STOPPED_FP_LOCKED_OUT(1177, FP_LOCKED_OUT),

    @UiEvent(doc = DREAM_STARTED) FACE_AUTH_STOPPED_DREAM_STARTED(1176, DREAM_STARTED),
    @UiEvent(doc = FP_LOCKED_OUT) FACE_AUTH_STOPPED_FP_LOCKED_OUT(1177, FP_LOCKED_OUT),
    @UiEvent(doc = FACE_AUTH_STOPPED_ON_USER_INPUT)
    FACE_AUTH_STOPPED_USER_INPUT_ON_BOUNCER(1178, FACE_AUTH_STOPPED_ON_USER_INPUT),

    @UiEvent(doc = KEYGUARD_GOING_AWAY)
    FACE_AUTH_STOPPED_KEYGUARD_GOING_AWAY(1179, KEYGUARD_GOING_AWAY),

    @UiEvent(doc = CAMERA_LAUNCHED)
    FACE_AUTH_UPDATED_CAMERA_LAUNCHED(1180, CAMERA_LAUNCHED),

    @UiEvent(doc = FP_AUTHENTICATED)
    FACE_AUTH_UPDATED_FP_AUTHENTICATED(1181, FP_AUTHENTICATED),

    @UiEvent(doc = GOING_TO_SLEEP)
    FACE_AUTH_UPDATED_GOING_TO_SLEEP(1182, GOING_TO_SLEEP),

    @UiEvent(doc = CAMERA_LAUNCHED) FACE_AUTH_UPDATED_CAMERA_LAUNCHED(1180, CAMERA_LAUNCHED),
    @UiEvent(doc = FP_AUTHENTICATED) FACE_AUTH_UPDATED_FP_AUTHENTICATED(1181, FP_AUTHENTICATED),
    @UiEvent(doc = GOING_TO_SLEEP) FACE_AUTH_UPDATED_GOING_TO_SLEEP(1182, GOING_TO_SLEEP),
    @UiEvent(doc = FINISHED_GOING_TO_SLEEP)
    FACE_AUTH_STOPPED_FINISHED_GOING_TO_SLEEP(1183, FINISHED_GOING_TO_SLEEP),

    @UiEvent(doc = KEYGUARD_INIT)
    FACE_AUTH_UPDATED_ON_KEYGUARD_INIT(1189, KEYGUARD_INIT),

    @UiEvent(doc = KEYGUARD_RESET)
    FACE_AUTH_UPDATED_KEYGUARD_RESET(1185, KEYGUARD_RESET),

    @UiEvent(doc = USER_SWITCHING)
    FACE_AUTH_UPDATED_USER_SWITCHING(1186, USER_SWITCHING),

    @UiEvent(doc = KEYGUARD_INIT) FACE_AUTH_UPDATED_ON_KEYGUARD_INIT(1189, KEYGUARD_INIT),
    @UiEvent(doc = KEYGUARD_RESET) FACE_AUTH_UPDATED_KEYGUARD_RESET(1185, KEYGUARD_RESET),
    @UiEvent(doc = USER_SWITCHING) FACE_AUTH_UPDATED_USER_SWITCHING(1186, USER_SWITCHING),
    @UiEvent(doc = FACE_AUTHENTICATED)
    FACE_AUTH_UPDATED_ON_FACE_AUTHENTICATED(1187, FACE_AUTHENTICATED),

    @UiEvent(doc = BIOMETRIC_ENABLED)
    FACE_AUTH_UPDATED_BIOMETRIC_ENABLED_ON_KEYGUARD(1188, BIOMETRIC_ENABLED);

    override fun getId(): Int = this.id

    /** Convert [extraInfo] to a human-readable string. By default, this is empty. */
    open fun extraInfoToString(): String = ""
}

private val apiRequestReasonToUiEvent =
+76 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.keyguard

import android.content.res.Resources
import android.os.Build
import android.os.PowerManager
import com.android.systemui.Dumpable
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.dump.DumpManager
import com.android.systemui.util.settings.GlobalSettings
import java.io.PrintWriter
import java.util.stream.Collectors
import javax.inject.Inject

/** Determines which device wake-ups should trigger face authentication. */
@SysUISingleton
class FaceWakeUpTriggersConfig
@Inject
constructor(@Main resources: Resources, globalSettings: GlobalSettings, dumpManager: DumpManager) :
    Dumpable {
    private val defaultTriggerFaceAuthOnWakeUpFrom: Set<Int> =
        resources.getIntArray(R.array.config_face_auth_wake_up_triggers).toSet()
    private val triggerFaceAuthOnWakeUpFrom: Set<Int>

    init {
        triggerFaceAuthOnWakeUpFrom =
            if (Build.IS_DEBUGGABLE) {
                // Update face wake triggers via adb on debuggable builds:
                // ie: adb shell settings put global face_wake_triggers "1\|4" &&
                //     adb shell am crash com.android.systemui
                processStringArray(
                    globalSettings.getString("face_wake_triggers"),
                    defaultTriggerFaceAuthOnWakeUpFrom
                )
            } else {
                defaultTriggerFaceAuthOnWakeUpFrom
            }
        dumpManager.registerDumpable(this)
    }

    fun shouldTriggerFaceAuthOnWakeUpFrom(@PowerManager.WakeReason pmWakeReason: Int): Boolean {
        return triggerFaceAuthOnWakeUpFrom.contains(pmWakeReason)
    }

    override fun dump(pw: PrintWriter, args: Array<out String>) {
        pw.println("FaceWakeUpTriggers:")
        for (pmWakeReason in triggerFaceAuthOnWakeUpFrom) {
            pw.println("    ${PowerManager.wakeReasonToString(pmWakeReason)}")
        }
    }

    /** Convert a pipe-separated set of integers into a set of ints. */
    private fun processStringArray(stringSetting: String?, default: Set<Int>): Set<Int> {
        return stringSetting?.let {
            stringSetting.split("|").stream().map(Integer::parseInt).collect(Collectors.toSet())
        }
            ?: default
    }
}
+34 −14
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_TRUST_ENABL
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_STOPPED_USER_INPUT_ON_BOUNCER;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALL_AUTHENTICATORS_REGISTERED;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_DREAM_STOPPED;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_DURING_CANCELLATION;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_ENROLLMENTS_CHANGED;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_TRIGGERED_FACE_LOCKOUT_RESET;
@@ -303,6 +302,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            }
        }
    };
    private final FaceWakeUpTriggersConfig mFaceWakeUpTriggersConfig;

    HashMap<Integer, SimData> mSimDatas = new HashMap<>();
    HashMap<Integer, ServiceState> mServiceStates = new HashMap<>();
@@ -1823,11 +1823,21 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
        }
    }

    protected void handleStartedWakingUp() {
    protected void handleStartedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
        Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
        Assert.isMainThread();
        updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE, FACE_AUTH_UPDATED_STARTED_WAKING_UP);
        requestActiveUnlock(ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE, "wakingUp");

        updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
        if (mFaceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(pmWakeReason)) {
            FACE_AUTH_UPDATED_STARTED_WAKING_UP.setExtraInfo(pmWakeReason);
            updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
                    FACE_AUTH_UPDATED_STARTED_WAKING_UP);
            requestActiveUnlock(ActiveUnlockConfig.ACTIVE_UNLOCK_REQUEST_ORIGIN.WAKE, "wakingUp - "
                    + PowerManager.wakeReasonToString(pmWakeReason));
        } else {
            mLogger.logSkipUpdateFaceListeningOnWakeup(pmWakeReason);
        }

        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
@@ -1879,12 +1889,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                cb.onDreamingStateChanged(mIsDreaming);
            }
        }
        if (mIsDreaming) {
        updateFingerprintListeningState(BIOMETRIC_ACTION_UPDATE);
        if (mIsDreaming) {
            updateFaceListeningState(BIOMETRIC_ACTION_STOP, FACE_AUTH_STOPPED_DREAM_STARTED);
        } else {
            updateBiometricListeningState(BIOMETRIC_ACTION_UPDATE,
                    FACE_AUTH_TRIGGERED_DREAM_STOPPED);
        }
    }

@@ -1964,7 +1971,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            PackageManager packageManager,
            @Nullable FaceManager faceManager,
            @Nullable FingerprintManager fingerprintManager,
            @Nullable BiometricManager biometricManager) {
            @Nullable BiometricManager biometricManager,
            FaceWakeUpTriggersConfig faceWakeUpTriggersConfig) {
        mContext = context;
        mSubscriptionManager = subscriptionManager;
        mTelephonyListenerManager = telephonyListenerManager;
@@ -2003,6 +2011,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                        R.array.config_face_acquire_device_entry_ignorelist))
                .boxed()
                .collect(Collectors.toSet());
        mFaceWakeUpTriggersConfig = faceWakeUpTriggersConfig;

        mHandler = new Handler(mainLooper) {
            @Override
@@ -2052,7 +2061,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
                        break;
                    case MSG_STARTED_WAKING_UP:
                        Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
                        handleStartedWakingUp();
                        handleStartedWakingUp(msg.arg1);
                        Trace.endSection();
                        break;
                    case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
@@ -2799,8 +2808,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab
            // Waiting for ERROR_CANCELED before requesting auth again
            return;
        }
        mLogger.logStartedListeningForFace(mFaceRunningState, faceAuthUiEvent.getReason());
        mUiEventLogger.log(faceAuthUiEvent, getKeyguardSessionId());
        mLogger.logStartedListeningForFace(mFaceRunningState, faceAuthUiEvent);
        mUiEventLogger.logWithInstanceIdAndPosition(
                faceAuthUiEvent,
                0,
                null,
                getKeyguardSessionId(),
                faceAuthUiEvent.getExtraInfo()
        );

        if (unlockPossible) {
            mFaceCancelSignal = new CancellationSignal();
@@ -3579,11 +3594,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpab

    // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
    // (KeyguardViewMediator, KeyguardHostView)
    public void dispatchStartedWakingUp() {
    /**
     * Dispatch wakeup events to:
     *  - update biometric listening states
     *  - send to registered KeyguardUpdateMonitorCallbacks
     */
    public void dispatchStartedWakingUp(@PowerManager.WakeReason int pmWakeReason) {
        synchronized (this) {
            mDeviceInteractive = true;
        }
        mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
        mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_WAKING_UP, pmWakeReason, 0));
    }

    public void dispatchStartedGoingToSleep(int why) {
+20 −3
Original line number Diff line number Diff line
@@ -17,9 +17,12 @@
package com.android.keyguard.logging

import android.hardware.biometrics.BiometricConstants.LockoutMode
import android.os.PowerManager
import android.os.PowerManager.WakeReason
import android.telephony.ServiceState
import android.telephony.SubscriptionInfo
import com.android.keyguard.ActiveUnlockConfig
import com.android.keyguard.FaceAuthUiEvent
import com.android.keyguard.KeyguardListenModel
import com.android.keyguard.KeyguardUpdateMonitorCallback
import com.android.systemui.plugins.log.LogBuffer
@@ -269,11 +272,19 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
        logBuffer.log(TAG, VERBOSE, { int1 = subId }, { "reportSimUnlocked(subId=$int1)" })
    }

    fun logStartedListeningForFace(faceRunningState: Int, faceAuthReason: String) {
    fun logStartedListeningForFace(faceRunningState: Int, faceAuthUiEvent: FaceAuthUiEvent) {
        logBuffer.log(TAG, VERBOSE, {
            int1 = faceRunningState
            str1 = faceAuthReason
        }, { "startListeningForFace(): $int1, reason: $str1" })
            str1 = faceAuthUiEvent.reason
            str2 = faceAuthUiEvent.extraInfoToString()
        }, { "startListeningForFace(): $int1, reason: $str1 $str2" })
    }

    fun logStartedListeningForFaceFromWakeUp(faceRunningState: Int, @WakeReason pmWakeReason: Int) {
        logBuffer.log(TAG, VERBOSE, {
            int1 = faceRunningState
            str1 = PowerManager.wakeReasonToString(pmWakeReason)
        }, { "startListeningForFace(): $int1, reason: wakeUp-$str1" })
    }

    fun logStoppedListeningForFace(faceRunningState: Int, faceAuthReason: String) {
@@ -383,4 +394,10 @@ class KeyguardUpdateMonitorLogger @Inject constructor(
        }, { "#update secure=$bool1 canDismissKeyguard=$bool2" +
                " trusted=$bool3 trustManaged=$bool4" })
    }

    fun logSkipUpdateFaceListeningOnWakeup(@WakeReason pmWakeReason: Int) {
        logBuffer.log(TAG, VERBOSE, {
            str1 = PowerManager.wakeReasonToString(pmWakeReason)
        }, { "Skip updating face listening state on wakeup from $str1"})
    }
}
Loading