Skip to content

Commit

Permalink
Merge ZP1A.240615.001
Browse files Browse the repository at this point in the history
Change-Id: I12c521b47e2268cf713023af4a9f9e89d481538f
  • Loading branch information
Scott Lobdell committed Jun 25, 2024
2 parents 2a133c0 + 8c9cd3c commit c37af63
Show file tree
Hide file tree
Showing 19 changed files with 349 additions and 89 deletions.
35 changes: 20 additions & 15 deletions cmds/installd/otapreopt_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,22 +59,27 @@ function infinite_source {
done
}

# Delegate to Pre-reboot Dexopt, a feature of ART Service.
# ART Service decides what to do with this request:
# - If Pre-reboot Dexopt is disabled or unsupported, the command returns
# non-zero. This is always the case if the current system is Android 14 or
# earlier.
# - If Pre-reboot Dexopt is enabled in synchronous mode, the command blocks
# until Pre-reboot Dexopt finishes, and returns zero no matter it succeeds or
# not. This is the default behavior if the current system is Android 15.
# - If Pre-reboot Dexopt is enabled in asynchronous mode, the command schedules
# an asynchronous job and returns 0 immediately. The job will then run by the
# job scheduler when the device is idle and charging.
if infinite_source | pm art on-ota-staged --slot "$TARGET_SLOT_SUFFIX"; then
# Handled by Pre-reboot Dexopt.
exit 0
PR_DEXOPT_JOB_VERSION="$(pm art pr-dexopt-job --version)"
if (( $? == 0 )) && (( $PR_DEXOPT_JOB_VERSION >= 2 )); then
# Delegate to Pre-reboot Dexopt, a feature of ART Service.
# ART Service decides what to do with this request:
# - If Pre-reboot Dexopt is disabled or unsupported, the command returns
# non-zero. This is always the case if the current system is Android 14 or
# earlier.
# - If Pre-reboot Dexopt is enabled in synchronous mode, the command blocks
# until Pre-reboot Dexopt finishes, and returns zero no matter it succeeds or
# not. This is the default behavior if the current system is Android 15.
# - If Pre-reboot Dexopt is enabled in asynchronous mode, the command schedules
# an asynchronous job and returns 0 immediately. The job will then run by the
# job scheduler when the device is idle and charging.
if infinite_source | pm art on-ota-staged --slot "$TARGET_SLOT_SUFFIX"; then
# Handled by Pre-reboot Dexopt.
exit 0
fi
echo "Pre-reboot Dexopt not enabled. Fall back to otapreopt."
else
echo "Pre-reboot Dexopt is too old. Fall back to otapreopt."
fi
echo "Pre-reboot Dexopt not enabled. Fall back to otapreopt."

if [ "$(/system/bin/otapreopt_chroot --version)" != 2 ]; then
# We require an updated chroot wrapper that reads dexopt commands from stdin.
Expand Down
6 changes: 3 additions & 3 deletions libs/gui/include/gui/LayerState.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,9 @@ struct layer_state_t {
layer_state_t::eFrameRateSelectionPriority | layer_state_t::eFixedTransformHintChanged;

// Changes affecting data sent to input.
static constexpr uint64_t INPUT_CHANGES = layer_state_t::eInputInfoChanged |
layer_state_t::eDropInputModeChanged | layer_state_t::eTrustedOverlayChanged |
layer_state_t::eLayerStackChanged;
static constexpr uint64_t INPUT_CHANGES = layer_state_t::eAlphaChanged |
layer_state_t::eInputInfoChanged | layer_state_t::eDropInputModeChanged |
layer_state_t::eTrustedOverlayChanged | layer_state_t::eLayerStackChanged;

// Changes that affect the visible region on a display.
static constexpr uint64_t VISIBLE_REGION_CHANGES = layer_state_t::GEOMETRY_CHANGES |
Expand Down
34 changes: 34 additions & 0 deletions services/inputflinger/PointerChoreographer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#if defined(__ANDROID__)
#include <gui/SurfaceComposerClient.h>
#endif
#include <input/Keyboard.h>
#include <input/PrintTools.h>
#include <unordered_set>

Expand Down Expand Up @@ -137,6 +138,7 @@ PointerChoreographer::PointerChoreographer(
mNotifiedPointerDisplayId(ui::LogicalDisplayId::INVALID),
mShowTouchesEnabled(false),
mStylusPointerIconEnabled(false),
mCurrentFocusedDisplay(ui::LogicalDisplayId::DEFAULT),
mRegisterListener(registerListener),
mUnregisterListener(unregisterListener) {}

Expand Down Expand Up @@ -168,6 +170,7 @@ void PointerChoreographer::notifyConfigurationChanged(const NotifyConfigurationC
}

void PointerChoreographer::notifyKey(const NotifyKeyArgs& args) {
fadeMouseCursorOnKeyPress(args);
mNextListener.notify(args);
}

Expand All @@ -177,6 +180,32 @@ void PointerChoreographer::notifyMotion(const NotifyMotionArgs& args) {
mNextListener.notify(newArgs);
}

void PointerChoreographer::fadeMouseCursorOnKeyPress(const android::NotifyKeyArgs& args) {
if (args.action == AKEY_EVENT_ACTION_UP || isMetaKey(args.keyCode)) {
return;
}
// Meta state for these keys is ignored for dismissing cursor while typing
constexpr static int32_t ALLOW_FADING_META_STATE_MASK = AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON |
AMETA_SCROLL_LOCK_ON | AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON | AMETA_SHIFT_ON;
if (args.metaState & ~ALLOW_FADING_META_STATE_MASK) {
// Do not fade if any other meta state is active
return;
}
if (!mPolicy.isInputMethodConnectionActive()) {
return;
}

std::scoped_lock _l(mLock);
ui::LogicalDisplayId targetDisplay = args.displayId;
if (targetDisplay == ui::LogicalDisplayId::INVALID) {
targetDisplay = mCurrentFocusedDisplay;
}
auto it = mMousePointersByDisplay.find(targetDisplay);
if (it != mMousePointersByDisplay.end()) {
it->second->fade(PointerControllerInterface::Transition::GRADUAL);
}
}

NotifyMotionArgs PointerChoreographer::processMotion(const NotifyMotionArgs& args) {
std::scoped_lock _l(mLock);

Expand Down Expand Up @@ -806,6 +835,11 @@ void PointerChoreographer::setPointerIconVisibility(ui::LogicalDisplayId display
}
}

void PointerChoreographer::setFocusedDisplay(ui::LogicalDisplayId displayId) {
std::scoped_lock lock(mLock);
mCurrentFocusedDisplay = displayId;
}

PointerChoreographer::ControllerConstructor PointerChoreographer::getMouseControllerConstructor(
ui::LogicalDisplayId displayId) {
std::function<std::shared_ptr<PointerControllerInterface>()> ctor =
Expand Down
8 changes: 8 additions & 0 deletions services/inputflinger/PointerChoreographer.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ class PointerChoreographerInterface : public InputListenerInterface {
*/
virtual void setPointerIconVisibility(ui::LogicalDisplayId displayId, bool visible) = 0;

/**
* Used by Dispatcher to notify changes in the current focused display.
*/
virtual void setFocusedDisplay(ui::LogicalDisplayId displayId) = 0;

/**
* This method may be called on any thread (usually by the input manager on a binder thread).
*/
Expand All @@ -97,6 +102,7 @@ class PointerChoreographer : public PointerChoreographerInterface {
bool setPointerIcon(std::variant<std::unique_ptr<SpriteIcon>, PointerIconStyle> icon,
ui::LogicalDisplayId displayId, DeviceId deviceId) override;
void setPointerIconVisibility(ui::LogicalDisplayId displayId, bool visible) override;
void setFocusedDisplay(ui::LogicalDisplayId displayId) override;

void notifyInputDevicesChanged(const NotifyInputDevicesChangedArgs& args) override;
void notifyConfigurationChanged(const NotifyConfigurationChangedArgs& args) override;
Expand Down Expand Up @@ -124,6 +130,7 @@ class PointerChoreographer : public PointerChoreographerInterface {
InputDeviceInfo* findInputDeviceLocked(DeviceId deviceId) REQUIRES(mLock);
bool canUnfadeOnDisplay(ui::LogicalDisplayId displayId) REQUIRES(mLock);

void fadeMouseCursorOnKeyPress(const NotifyKeyArgs& args);
NotifyMotionArgs processMotion(const NotifyMotionArgs& args);
NotifyMotionArgs processMouseEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
NotifyMotionArgs processTouchpadEventLocked(const NotifyMotionArgs& args) REQUIRES(mLock);
Expand Down Expand Up @@ -192,6 +199,7 @@ class PointerChoreographer : public PointerChoreographerInterface {
bool mShowTouchesEnabled GUARDED_BY(mLock);
bool mStylusPointerIconEnabled GUARDED_BY(mLock);
std::set<ui::LogicalDisplayId /*displayId*/> mDisplaysWithPointersHidden;
ui::LogicalDisplayId mCurrentFocusedDisplay GUARDED_BY(mLock);

protected:
using WindowListenerRegisterConsumer = std::function<std::vector<gui::WindowInfo>(
Expand Down
7 changes: 7 additions & 0 deletions services/inputflinger/dispatcher/InputDispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5523,6 +5523,13 @@ void InputDispatcher::setFocusedDisplay(ui::LogicalDisplayId displayId) {
synthesizeCancelationEventsForWindowLocked(windowHandle, options);
}
mFocusedDisplayId = displayId;
// Enqueue a command to run outside the lock to tell the policy that the focused display
// changed.
auto command = [this]() REQUIRES(mLock) {
scoped_unlock unlock(mLock);
mPolicy.notifyFocusedDisplayChanged(mFocusedDisplayId);
};
postCommandLocked(std::move(command));

// Only a window on the focused display can have Pointer Capture, so disable the active
// Pointer Capture session if there is one, since the focused display changed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ class InputDispatcherPolicyInterface {
InputDeviceSensorAccuracy accuracy) = 0;
virtual void notifyVibratorState(int32_t deviceId, bool isOn) = 0;

/*
* Notifies the system that focused display has changed.
*/
virtual void notifyFocusedDisplayChanged(ui::LogicalDisplayId displayId) = 0;

/* Filters an input event.
* Return true to dispatch the event unmodified, false to consume the event.
* A filter can also transform and inject events later by passing POLICY_FLAG_FILTERED
Expand Down
7 changes: 7 additions & 0 deletions services/inputflinger/include/NotifyArgsBuilders.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <attestation/HmacKeyManager.h>
#include <input/Input.h>
#include <input/InputEventBuilders.h>
#include <input/Keyboard.h>
#include <utils/Timers.h> // for nsecs_t, systemTime

#include <vector>
Expand Down Expand Up @@ -206,6 +207,12 @@ class KeyArgsBuilder {
return *this;
}

KeyArgsBuilder& metaState(int32_t metaState) {
mMetaState |= metaState;
mMetaState = normalizeMetaState(/*oldMetaState=*/mMetaState);
return *this;
}

NotifyKeyArgs build() const {
return {mEventId,
mEventTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ class PointerChoreographerPolicyInterface {
*/
virtual void notifyPointerDisplayIdChanged(ui::LogicalDisplayId displayId,
const FloatPoint& position) = 0;

/* Returns true if any InputConnection is currently active. */
virtual bool isInputMethodConnectionActive() = 0;
};

} // namespace android
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,6 @@ std::list<NotifyArgs> KeyboardInputMapper::cancelAllDownKeys(nsecs_t when) {
void KeyboardInputMapper::onKeyDownProcessed(nsecs_t downTime) {
InputReaderContext& context = *getContext();
context.setLastKeyDownTimestamp(downTime);
// TODO(b/338652288): Move cursor fading logic into PointerChoreographer.
// Ignore meta keys or multiple simultaneous down keys as they are likely to be keyboard
// shortcuts
bool shouldHideCursor = mKeyDowns.size() == 1 && !isMetaKey(mKeyDowns[0].keyCode);
Expand Down
24 changes: 24 additions & 0 deletions services/inputflinger/tests/FakeInputDispatcherPolicy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,24 @@ void FakeInputDispatcherPolicy::setConsumeKeyBeforeDispatching(bool consumeKeyBe
mConsumeKeyBeforeDispatching = consumeKeyBeforeDispatching;
}

void FakeInputDispatcherPolicy::assertFocusedDisplayNotified(ui::LogicalDisplayId expectedDisplay) {
std::unique_lock lock(mLock);
base::ScopedLockAssertion assumeLocked(mLock);

if (!mFocusedDisplayNotifiedCondition.wait_for(lock, 100ms,
[this, expectedDisplay]() REQUIRES(mLock) {
if (!mNotifiedFocusedDisplay.has_value() ||
mNotifiedFocusedDisplay.value() !=
expectedDisplay) {
return false;
}
return true;
})) {
ADD_FAILURE() << "Timed out waiting for notifyFocusedDisplayChanged(" << expectedDisplay
<< ") to be called.";
}
}

void FakeInputDispatcherPolicy::assertUserActivityNotPoked() {
std::unique_lock lock(mLock);
base::ScopedLockAssertion assumeLocked(mLock);
Expand Down Expand Up @@ -473,4 +491,10 @@ void FakeInputDispatcherPolicy::assertFilterInputEventWasCalledInternal(
mFilteredEvent = nullptr;
}

void FakeInputDispatcherPolicy::notifyFocusedDisplayChanged(ui::LogicalDisplayId displayId) {
std::scoped_lock lock(mLock);
mNotifiedFocusedDisplay = displayId;
mFocusedDisplayNotifiedCondition.notify_all();
}

} // namespace android
5 changes: 5 additions & 0 deletions services/inputflinger/tests/FakeInputDispatcherPolicy.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
void assertUnhandledKeyReported(int32_t keycode);
void assertUnhandledKeyNotReported();
void setConsumeKeyBeforeDispatching(bool consumeKeyBeforeDispatching);
void assertFocusedDisplayNotified(ui::LogicalDisplayId expectedDisplay);

private:
std::mutex mLock;
Expand All @@ -126,6 +127,9 @@ class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {

std::condition_variable mPointerCaptureChangedCondition;

std::optional<ui::LogicalDisplayId> mNotifiedFocusedDisplay GUARDED_BY(mLock);
std::condition_variable mFocusedDisplayNotifiedCondition;

std::optional<PointerCaptureRequest> mPointerCaptureRequest GUARDED_BY(mLock);
// ANR handling
std::queue<std::shared_ptr<InputApplicationHandle>> mAnrApplications GUARDED_BY(mLock);
Expand Down Expand Up @@ -201,6 +205,7 @@ class FakeInputDispatcherPolicy : public InputDispatcherPolicyInterface {
void notifyDropWindow(const sp<IBinder>& token, float x, float y) override;
void notifyDeviceInteraction(int32_t deviceId, nsecs_t timestamp,
const std::set<gui::Uid>& uids) override;
void notifyFocusedDisplayChanged(ui::LogicalDisplayId displayId) override;

void assertFilterInputEventWasCalledInternal(
const std::function<void(const InputEvent&)>& verify);
Expand Down
8 changes: 8 additions & 0 deletions services/inputflinger/tests/InputDispatcher_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8577,6 +8577,8 @@ class InputDispatcherFocusOnTwoDisplaysTest : public InputDispatcherTest {
// Set focus to second display window.
// Set focus display to second one.
mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
mFakePolicy->assertFocusedDisplayNotified(SECOND_DISPLAY_ID);

// Set focus window for second display.
mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
windowInSecondary->setFocusable(true);
Expand Down Expand Up @@ -11066,6 +11068,7 @@ TEST_F(InputDispatcherPointerCaptureTests, MultiDisplayPointerCapture) {

// Make the second display the focused display.
mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
mFakePolicy->assertFocusedDisplayNotified(SECOND_DISPLAY_ID);

// This causes the first window to lose pointer capture, and it's unable to request capture.
mWindow->consumeCaptureEvent(false);
Expand Down Expand Up @@ -13769,4 +13772,9 @@ TEST_F(InputDispatcherPointerInWindowTest, MultipleDevicesControllingOneMouse) {
/*pointerId=*/0));
}

TEST_F(InputDispatcherTest, FocusedDisplayChangeIsNotified) {
mDispatcher->setFocusedDisplay(SECOND_DISPLAY_ID);
mFakePolicy->assertFocusedDisplayNotified(SECOND_DISPLAY_ID);
}

} // namespace android::inputdispatcher
1 change: 1 addition & 0 deletions services/inputflinger/tests/InterfaceMocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ class MockPointerChoreographerPolicyInterface : public PointerChoreographerPolic
(PointerControllerInterface::ControllerType), (override));
MOCK_METHOD(void, notifyPointerDisplayIdChanged,
(ui::LogicalDisplayId displayId, const FloatPoint& position), (override));
MOCK_METHOD(bool, isInputMethodConnectionActive, (), (override));
};

} // namespace android
45 changes: 0 additions & 45 deletions services/inputflinger/tests/KeyboardInputMapper_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,6 @@ class KeyboardInputMapperUnitTest : public InputMapperUnitTest {
AINPUT_SOURCE_KEYBOARD);
}

void testPointerVisibilityForKeys(const std::vector<int32_t>& keyCodes, bool expectVisible) {
for (int32_t keyCode : keyCodes) {
process(EV_KEY, keyCode, 1);
process(EV_SYN, SYN_REPORT, 0);
process(EV_KEY, keyCode, 0);
process(EV_SYN, SYN_REPORT, 0);
}
}

void testTouchpadTapStateForKeys(const std::vector<int32_t>& keyCodes,
const bool expectPrevent) {
if (expectPrevent) {
Expand All @@ -94,42 +85,6 @@ class KeyboardInputMapperUnitTest : public InputMapperUnitTest {
}
};

/**
* Pointer visibility should remain unaffected if there is no active Input Method Connection
*/
TEST_F(KeyboardInputMapperUnitTest, KeystrokesWithoutIMeConnectionDoesNotHidePointer) {
testPointerVisibilityForKeys({KEY_0, KEY_A, KEY_LEFTCTRL}, /* expectVisible= */ true);
}

/**
* Pointer should hide if there is a active Input Method Connection
*/
TEST_F(KeyboardInputMapperUnitTest, AlphanumericKeystrokesWithIMeConnectionHidePointer) {
mFakePolicy->setIsInputMethodConnectionActive(true);
testPointerVisibilityForKeys({KEY_0, KEY_A}, /* expectVisible= */ false);
}

/**
* Pointer should still hide if touchpad taps are already disabled
*/
TEST_F(KeyboardInputMapperUnitTest, AlphanumericKeystrokesWithTouchpadTapDisabledHidePointer) {
mFakePolicy->setIsInputMethodConnectionActive(true);
EXPECT_CALL(mMockInputReaderContext, isPreventingTouchpadTaps).WillRepeatedly(Return(true));
testPointerVisibilityForKeys({KEY_0, KEY_A}, /* expectVisible= */ false);
}

/**
* Pointer visibility should remain unaffected by meta keys even if Input Method Connection is
* active
*/
TEST_F(KeyboardInputMapperUnitTest, MetaKeystrokesWithIMeConnectionDoesNotHidePointer) {
mFakePolicy->setIsInputMethodConnectionActive(true);
std::vector<int32_t> metaKeys{KEY_LEFTALT, KEY_RIGHTALT, KEY_LEFTSHIFT, KEY_RIGHTSHIFT,
KEY_FN, KEY_LEFTCTRL, KEY_RIGHTCTRL, KEY_LEFTMETA,
KEY_RIGHTMETA, KEY_CAPSLOCK, KEY_NUMLOCK, KEY_SCROLLLOCK};
testPointerVisibilityForKeys(metaKeys, /* expectVisible= */ true);
}

/**
* Touchpad tap should not be disabled if there is no active Input Method Connection
*/
Expand Down
Loading

0 comments on commit c37af63

Please sign in to comment.