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

Commit 14afbba6 authored by Jeff Brown's avatar Jeff Brown Committed by Android Git Automerger
Browse files

am ea6b8188: Merge "Improve ANR diagnostics." into jb-dev

* commit 'ea6b8188':
  Improve ANR diagnostics.
parents a20d99b1 ea6b8188
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -493,7 +493,7 @@ public final class Choreographer {
            if (jitterNanos >= mFrameIntervalNanos) {
            if (jitterNanos >= mFrameIntervalNanos) {
                final long skippedFrames = jitterNanos / mFrameIntervalNanos;
                final long skippedFrames = jitterNanos / mFrameIntervalNanos;
                if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
                if (skippedFrames >= SKIPPED_FRAME_WARNING_LIMIT) {
                    Log.w(TAG, "Skipped " + skippedFrames + " frames!  "
                    Log.i(TAG, "Skipped " + skippedFrames + " frames!  "
                            + "The application may be doing too much work on its main thread.");
                            + "The application may be doing too much work on its main thread.");
                }
                }
                final long lastFrameOffset = jitterNanos % mFrameIntervalNanos;
                final long lastFrameOffset = jitterNanos % mFrameIntervalNanos;
+124 −43
Original line number Original line Diff line number Diff line
@@ -56,6 +56,8 @@


#define INDENT "  "
#define INDENT "  "
#define INDENT2 "    "
#define INDENT2 "    "
#define INDENT3 "      "
#define INDENT4 "        "


namespace android {
namespace android {


@@ -78,6 +80,9 @@ const nsecs_t STALE_EVENT_TIMEOUT = 10000 * 1000000LL; // 10sec
// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
// queue of waiting unfinished events, then ANRs will similarly be delayed by one second.
const nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec
const nsecs_t STREAM_AHEAD_EVENT_TIMEOUT = 500 * 1000000LL; // 0.5sec


// Log a warning when an event takes longer than this to process, even if an ANR does not occur.
const nsecs_t SLOW_EVENT_PROCESSING_WARNING_TIMEOUT = 2000 * 1000000LL; // 2sec



static inline nsecs_t now() {
static inline nsecs_t now() {
    return systemTime(SYSTEM_TIME_MONOTONIC);
    return systemTime(SYSTEM_TIME_MONOTONIC);
@@ -897,11 +902,11 @@ int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
        const EventEntry* entry,
        const EventEntry* entry,
        const sp<InputApplicationHandle>& applicationHandle,
        const sp<InputApplicationHandle>& applicationHandle,
        const sp<InputWindowHandle>& windowHandle,
        const sp<InputWindowHandle>& windowHandle,
        nsecs_t* nextWakeupTime) {
        nsecs_t* nextWakeupTime, const char* reason) {
    if (applicationHandle == NULL && windowHandle == NULL) {
    if (applicationHandle == NULL && windowHandle == NULL) {
        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY) {
#if DEBUG_FOCUS
#if DEBUG_FOCUS
            ALOGD("Waiting for system to become ready for input.");
            ALOGD("Waiting for system to become ready for input.  Reason: %s", reason);
#endif
#endif
            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
            mInputTargetWaitCause = INPUT_TARGET_WAIT_CAUSE_SYSTEM_NOT_READY;
            mInputTargetWaitStartTime = currentTime;
            mInputTargetWaitStartTime = currentTime;
@@ -912,8 +917,9 @@ int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,
    } else {
    } else {
        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
        if (mInputTargetWaitCause != INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY) {
#if DEBUG_FOCUS
#if DEBUG_FOCUS
            ALOGD("Waiting for application to become ready for input: %s",
            ALOGD("Waiting for application to become ready for input: %s.  Reason: %s",
                    getApplicationWindowLabelLocked(applicationHandle, windowHandle).string());
                    getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
                    reason);
#endif
#endif
            nsecs_t timeout;
            nsecs_t timeout;
            if (windowHandle != NULL) {
            if (windowHandle != NULL) {
@@ -946,7 +952,7 @@ int32_t InputDispatcher::handleTargetsNotReadyLocked(nsecs_t currentTime,


    if (currentTime >= mInputTargetWaitTimeoutTime) {
    if (currentTime >= mInputTargetWaitTimeoutTime) {
        onANRLocked(currentTime, applicationHandle, windowHandle,
        onANRLocked(currentTime, applicationHandle, windowHandle,
                entry->eventTime, mInputTargetWaitStartTime);
                entry->eventTime, mInputTargetWaitStartTime, reason);


        // Force poll loop to wake up immediately on next iteration once we get the
        // Force poll loop to wake up immediately on next iteration once we get the
        // ANR response back from the policy.
        // ANR response back from the policy.
@@ -1017,13 +1023,11 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,
    // then drop the event.
    // then drop the event.
    if (mFocusedWindowHandle == NULL) {
    if (mFocusedWindowHandle == NULL) {
        if (mFocusedApplicationHandle != NULL) {
        if (mFocusedApplicationHandle != NULL) {
#if DEBUG_FOCUS
            ALOGD("Waiting because there is no focused window but there is a "
                    "focused application that may eventually add a window: %s.",
                    getApplicationWindowLabelLocked(mFocusedApplicationHandle, NULL).string());
#endif
            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
                    mFocusedApplicationHandle, NULL, nextWakeupTime);
                    mFocusedApplicationHandle, NULL, nextWakeupTime,
                    "Waiting because no window has focus but there is a "
                    "focused application that may eventually add a window "
                    "when it finishes starting up.");
            goto Unresponsive;
            goto Unresponsive;
        }
        }


@@ -1040,21 +1044,18 @@ int32_t InputDispatcher::findFocusedWindowTargetsLocked(nsecs_t currentTime,


    // If the currently focused window is paused then keep waiting.
    // If the currently focused window is paused then keep waiting.
    if (mFocusedWindowHandle->getInfo()->paused) {
    if (mFocusedWindowHandle->getInfo()->paused) {
#if DEBUG_FOCUS
        ALOGD("Waiting because focused window is paused.");
#endif
        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime);
                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime,
                "Waiting because the focused window is paused.");
        goto Unresponsive;
        goto Unresponsive;
    }
    }


    // If the currently focused window is still working on previous events then keep waiting.
    // If the currently focused window is still working on previous events then keep waiting.
    if (!isWindowReadyForMoreInputLocked(currentTime, mFocusedWindowHandle, entry)) {
    if (!isWindowReadyForMoreInputLocked(currentTime, mFocusedWindowHandle, entry)) {
#if DEBUG_FOCUS
        ALOGD("Waiting because focused window still processing previous input.");
#endif
        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
        injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime);
                mFocusedApplicationHandle, mFocusedWindowHandle, nextWakeupTime,
                "Waiting because the focused window has not finished "
                "processing the input events that were previously delivered to it.");
        goto Unresponsive;
        goto Unresponsive;
    }
    }


@@ -1210,11 +1211,9 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
        // it is invisible) then wait for it.  Any other focused window may in
        // it is invisible) then wait for it.  Any other focused window may in
        // fact be in ANR state.
        // fact be in ANR state.
        if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
        if (topErrorWindowHandle != NULL && newTouchedWindowHandle != topErrorWindowHandle) {
#if DEBUG_FOCUS
            ALOGD("Waiting because system error window is pending.");
#endif
            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
            injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
                    NULL, NULL, nextWakeupTime);
                    NULL, NULL, nextWakeupTime,
                    "Waiting because a system error window is about to be displayed.");
            injectionPermission = INJECTION_PERMISSION_UNKNOWN;
            injectionPermission = INJECTION_PERMISSION_UNKNOWN;
            goto Unresponsive;
            goto Unresponsive;
        }
        }
@@ -1241,14 +1240,11 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
                // but not yet put up a window and the user is starting to get impatient.
                // but not yet put up a window and the user is starting to get impatient.
                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
                        && mFocusedApplicationHandle != NULL) {
                        && mFocusedApplicationHandle != NULL) {
#if DEBUG_FOCUS
                    ALOGD("Waiting because there is no touched window but there is a "
                            "focused application that may eventually add a new window: %s.",
                            getApplicationWindowLabelLocked(
                                    mFocusedApplicationHandle, NULL).string());
#endif
                    injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
                    injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
                            mFocusedApplicationHandle, NULL, nextWakeupTime);
                            mFocusedApplicationHandle, NULL, nextWakeupTime,
                            "Waiting because there is no touchable window that can "
                            "handle the event but there is focused application that may "
                            "eventually add a new window when it finishes starting up.");
                    goto Unresponsive;
                    goto Unresponsive;
                }
                }


@@ -1412,21 +1408,18 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
        if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
        if (touchedWindow.targetFlags & InputTarget::FLAG_FOREGROUND) {
            // If the touched window is paused then keep waiting.
            // If the touched window is paused then keep waiting.
            if (touchedWindow.windowHandle->getInfo()->paused) {
            if (touchedWindow.windowHandle->getInfo()->paused) {
#if DEBUG_FOCUS
                ALOGD("Waiting because touched window is paused.");
#endif
                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
                        NULL, touchedWindow.windowHandle, nextWakeupTime);
                        NULL, touchedWindow.windowHandle, nextWakeupTime,
                        "Waiting because the touched window is paused.");
                goto Unresponsive;
                goto Unresponsive;
            }
            }


            // If the touched window is still working on previous events then keep waiting.
            // If the touched window is still working on previous events then keep waiting.
            if (!isWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle, entry)) {
            if (!isWindowReadyForMoreInputLocked(currentTime, touchedWindow.windowHandle, entry)) {
#if DEBUG_FOCUS
                ALOGD("Waiting because touched window still processing previous input.");
#endif
                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
                injectionResult = handleTargetsNotReadyLocked(currentTime, entry,
                        NULL, touchedWindow.windowHandle, nextWakeupTime);
                        NULL, touchedWindow.windowHandle, nextWakeupTime,
                        "Waiting because the touched window has not finished "
                        "processing the input events that were previously delivered to it.");
                goto Unresponsive;
                goto Unresponsive;
            }
            }
        }
        }
@@ -1897,6 +1890,7 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
    while (connection->status == Connection::STATUS_NORMAL
    while (connection->status == Connection::STATUS_NORMAL
            && !connection->outboundQueue.isEmpty()) {
            && !connection->outboundQueue.isEmpty()) {
        DispatchEntry* dispatchEntry = connection->outboundQueue.head;
        DispatchEntry* dispatchEntry = connection->outboundQueue.head;
        dispatchEntry->deliveryTime = currentTime;


        // Publish the event.
        // Publish the event.
        status_t status;
        status_t status;
@@ -3099,7 +3093,65 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
        dump.append(INDENT "MonitoringChannels: <none>\n");
        dump.append(INDENT "MonitoringChannels: <none>\n");
    }
    }


    nsecs_t currentTime = now();

    if (!mInboundQueue.isEmpty()) {
        dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
        dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count());
        for (EventEntry* entry = mInboundQueue.head; entry; entry = entry->next) {
            dump.append(INDENT2);
            entry->appendDescription(dump);
            dump.appendFormat(", age=%01.1fms\n",
                    (currentTime - entry->eventTime) * 0.000001f);
        }
    } else {
        dump.append(INDENT "InboundQueue: <empty>\n");
    }

    if (!mConnectionsByFd.isEmpty()) {
        dump.append(INDENT "Connections:\n");
        for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
            const sp<Connection>& connection = mConnectionsByFd.valueAt(i);
            dump.appendFormat(INDENT2 "%d: channelName='%s', windowName='%s', "
                    "status=%s, monitor=%s, inputPublisherBlocked=%s\n",
                    i, connection->getInputChannelName(), connection->getWindowName(),
                    connection->getStatusLabel(), toString(connection->monitor),
                    toString(connection->inputPublisherBlocked));

            if (!connection->outboundQueue.isEmpty()) {
                dump.appendFormat(INDENT3 "OutboundQueue: length=%u\n",
                        connection->outboundQueue.count());
                for (DispatchEntry* entry = connection->outboundQueue.head; entry;
                        entry = entry->next) {
                    dump.append(INDENT4);
                    entry->eventEntry->appendDescription(dump);
                    dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, age=%01.1fms\n",
                            entry->targetFlags, entry->resolvedAction,
                            (currentTime - entry->eventEntry->eventTime) * 0.000001f);
                }
            } else {
                dump.append(INDENT3 "OutboundQueue: <empty>\n");
            }

            if (!connection->waitQueue.isEmpty()) {
                dump.appendFormat(INDENT3 "WaitQueue: length=%u\n",
                        connection->waitQueue.count());
                for (DispatchEntry* entry = connection->waitQueue.head; entry;
                        entry = entry->next) {
                    dump.append(INDENT4);
                    entry->eventEntry->appendDescription(dump);
                    dump.appendFormat(", targetFlags=0x%08x, resolvedAction=%d, "
                            "age=%01.1fms, wait=%01.1fms\n",
                            entry->targetFlags, entry->resolvedAction,
                            (currentTime - entry->eventEntry->eventTime) * 0.000001f,
                            (currentTime - entry->deliveryTime) * 0.000001f);
                }
            } else {
                dump.append(INDENT3 "WaitQueue: <empty>\n");
            }
        }
    } else {
        dump.append(INDENT "Connections: <none>\n");
    }


    if (isAppSwitchPendingLocked()) {
    if (isAppSwitchPendingLocked()) {
        dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
        dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n",
@@ -3214,6 +3266,7 @@ void InputDispatcher::onDispatchCycleFinishedLocked(
    CommandEntry* commandEntry = postCommandLocked(
    CommandEntry* commandEntry = postCommandLocked(
            & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
            & InputDispatcher::doDispatchCycleFinishedLockedInterruptible);
    commandEntry->connection = connection;
    commandEntry->connection = connection;
    commandEntry->eventTime = currentTime;
    commandEntry->seq = seq;
    commandEntry->seq = seq;
    commandEntry->handled = handled;
    commandEntry->handled = handled;
}
}
@@ -3231,12 +3284,12 @@ void InputDispatcher::onDispatchCycleBrokenLocked(
void InputDispatcher::onANRLocked(
void InputDispatcher::onANRLocked(
        nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
        nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
        const sp<InputWindowHandle>& windowHandle,
        const sp<InputWindowHandle>& windowHandle,
        nsecs_t eventTime, nsecs_t waitStartTime) {
        nsecs_t eventTime, nsecs_t waitStartTime, const char* reason) {
    ALOGI("Application is not responding: %s.  "
    ALOGI("Application is not responding: %s.  "
            "%01.1fms since event, %01.1fms since wait started",
            "It has been %01.1fms since event, %01.1fms since wait started.  Reason: %s",
            getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
            getApplicationWindowLabelLocked(applicationHandle, windowHandle).string(),
            (currentTime - eventTime) / 1000000.0,
            (currentTime - eventTime) / 1000000.0,
            (currentTime - waitStartTime) / 1000000.0);
            (currentTime - waitStartTime) / 1000000.0, reason);


    CommandEntry* commandEntry = postCommandLocked(
    CommandEntry* commandEntry = postCommandLocked(
            & InputDispatcher::doNotifyANRLockedInterruptible);
            & InputDispatcher::doNotifyANRLockedInterruptible);
@@ -3308,12 +3361,22 @@ void InputDispatcher::doInterceptKeyBeforeDispatchingLockedInterruptible(
void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(
        CommandEntry* commandEntry) {
        CommandEntry* commandEntry) {
    sp<Connection> connection = commandEntry->connection;
    sp<Connection> connection = commandEntry->connection;
    nsecs_t finishTime = commandEntry->eventTime;
    uint32_t seq = commandEntry->seq;
    uint32_t seq = commandEntry->seq;
    bool handled = commandEntry->handled;
    bool handled = commandEntry->handled;


    // Handle post-event policy actions.
    // Handle post-event policy actions.
    DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
    DispatchEntry* dispatchEntry = connection->findWaitQueueEntry(seq);
    if (dispatchEntry) {
    if (dispatchEntry) {
        nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime;
        if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) {
            String8 msg;
            msg.appendFormat("Window '%s' spent %01.1fms processing the last input event: ",
                    connection->getWindowName(), eventDuration * 0.000001f);
            dispatchEntry->eventEntry->appendDescription(msg);
            ALOGI("%s", msg.string());
        }

        bool restartEvent;
        bool restartEvent;
        if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
        if (dispatchEntry->eventEntry->type == EventEntry::TYPE_KEY) {
            KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
            KeyEntry* keyEntry = static_cast<KeyEntry*>(dispatchEntry->eventEntry);
@@ -3656,6 +3719,10 @@ InputDispatcher::ConfigurationChangedEntry::ConfigurationChangedEntry(nsecs_t ev
InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
InputDispatcher::ConfigurationChangedEntry::~ConfigurationChangedEntry() {
}
}


void InputDispatcher::ConfigurationChangedEntry::appendDescription(String8& msg) const {
    msg.append("ConfigurationChangedEvent()");
}



// --- InputDispatcher::DeviceResetEntry ---
// --- InputDispatcher::DeviceResetEntry ---


@@ -3667,6 +3734,10 @@ InputDispatcher::DeviceResetEntry::DeviceResetEntry(nsecs_t eventTime, int32_t d
InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
InputDispatcher::DeviceResetEntry::~DeviceResetEntry() {
}
}


void InputDispatcher::DeviceResetEntry::appendDescription(String8& msg) const {
    msg.appendFormat("DeviceResetEvent(deviceId=%d)", deviceId);
}



// --- InputDispatcher::KeyEntry ---
// --- InputDispatcher::KeyEntry ---


@@ -3685,6 +3756,11 @@ InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
InputDispatcher::KeyEntry::~KeyEntry() {
InputDispatcher::KeyEntry::~KeyEntry() {
}
}


void InputDispatcher::KeyEntry::appendDescription(String8& msg) const {
    msg.appendFormat("KeyEvent(action=%d, deviceId=%d, source=0x%08x)",
            action, deviceId, source);
}

void InputDispatcher::KeyEntry::recycle() {
void InputDispatcher::KeyEntry::recycle() {
    releaseInjectionState();
    releaseInjectionState();


@@ -3718,6 +3794,11 @@ InputDispatcher::MotionEntry::MotionEntry(nsecs_t eventTime,
InputDispatcher::MotionEntry::~MotionEntry() {
InputDispatcher::MotionEntry::~MotionEntry() {
}
}


void InputDispatcher::MotionEntry::appendDescription(String8& msg) const {
    msg.appendFormat("MotionEvent(action=%d, deviceId=%d, source=0x%08x)",
            action, deviceId, source);
}



// --- InputDispatcher::DispatchEntry ---
// --- InputDispatcher::DispatchEntry ---


@@ -3728,7 +3809,7 @@ InputDispatcher::DispatchEntry::DispatchEntry(EventEntry* eventEntry,
        seq(nextSeq()),
        seq(nextSeq()),
        eventEntry(eventEntry), targetFlags(targetFlags),
        eventEntry(eventEntry), targetFlags(targetFlags),
        xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
        xOffset(xOffset), yOffset(yOffset), scaleFactor(scaleFactor),
        resolvedAction(0), resolvedFlags(0) {
        deliveryTime(0), resolvedAction(0), resolvedFlags(0) {
    eventEntry->refCount += 1;
    eventEntry->refCount += 1;
}
}


+9 −2
Original line number Original line Diff line number Diff line
@@ -440,6 +440,8 @@ private:


        void release();
        void release();


        virtual void appendDescription(String8& msg) const = 0;

    protected:
    protected:
        EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags);
        EventEntry(int32_t type, nsecs_t eventTime, uint32_t policyFlags);
        virtual ~EventEntry();
        virtual ~EventEntry();
@@ -448,6 +450,7 @@ private:


    struct ConfigurationChangedEntry : EventEntry {
    struct ConfigurationChangedEntry : EventEntry {
        ConfigurationChangedEntry(nsecs_t eventTime);
        ConfigurationChangedEntry(nsecs_t eventTime);
        virtual void appendDescription(String8& msg) const;


    protected:
    protected:
        virtual ~ConfigurationChangedEntry();
        virtual ~ConfigurationChangedEntry();
@@ -457,6 +460,7 @@ private:
        int32_t deviceId;
        int32_t deviceId;


        DeviceResetEntry(nsecs_t eventTime, int32_t deviceId);
        DeviceResetEntry(nsecs_t eventTime, int32_t deviceId);
        virtual void appendDescription(String8& msg) const;


    protected:
    protected:
        virtual ~DeviceResetEntry();
        virtual ~DeviceResetEntry();
@@ -488,6 +492,7 @@ private:
                int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
                int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
                int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
                int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
                int32_t repeatCount, nsecs_t downTime);
                int32_t repeatCount, nsecs_t downTime);
        virtual void appendDescription(String8& msg) const;
        void recycle();
        void recycle();


    protected:
    protected:
@@ -516,6 +521,7 @@ private:
                float xPrecision, float yPrecision,
                float xPrecision, float yPrecision,
                nsecs_t downTime, uint32_t pointerCount,
                nsecs_t downTime, uint32_t pointerCount,
                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
                const PointerProperties* pointerProperties, const PointerCoords* pointerCoords);
        virtual void appendDescription(String8& msg) const;


    protected:
    protected:
        virtual ~MotionEntry();
        virtual ~MotionEntry();
@@ -530,6 +536,7 @@ private:
        float xOffset;
        float xOffset;
        float yOffset;
        float yOffset;
        float scaleFactor;
        float scaleFactor;
        nsecs_t deliveryTime; // time when the event was actually delivered


        // Set to the resolved action and flags when the event is enqueued.
        // Set to the resolved action and flags when the event is enqueued.
        int32_t resolvedAction;
        int32_t resolvedAction;
@@ -978,7 +985,7 @@ private:
    int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
    int32_t handleTargetsNotReadyLocked(nsecs_t currentTime, const EventEntry* entry,
            const sp<InputApplicationHandle>& applicationHandle,
            const sp<InputApplicationHandle>& applicationHandle,
            const sp<InputWindowHandle>& windowHandle,
            const sp<InputWindowHandle>& windowHandle,
            nsecs_t* nextWakeupTime);
            nsecs_t* nextWakeupTime, const char* reason);
    void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
    void resumeAfterTargetsNotReadyTimeoutLocked(nsecs_t newTimeout,
            const sp<InputChannel>& inputChannel);
            const sp<InputChannel>& inputChannel);
    nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime);
    nsecs_t getTimeSpentWaitingForApplicationLocked(nsecs_t currentTime);
@@ -1056,7 +1063,7 @@ private:
    void onANRLocked(
    void onANRLocked(
            nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
            nsecs_t currentTime, const sp<InputApplicationHandle>& applicationHandle,
            const sp<InputWindowHandle>& windowHandle,
            const sp<InputWindowHandle>& windowHandle,
            nsecs_t eventTime, nsecs_t waitStartTime);
            nsecs_t eventTime, nsecs_t waitStartTime, const char* reason);


    // Outbound policy interactions.
    // Outbound policy interactions.
    void doNotifyConfigurationChangedInterruptible(CommandEntry* commandEntry);
    void doNotifyConfigurationChangedInterruptible(CommandEntry* commandEntry);