Merge "BLASTBufferQueue: Initialize transform hint on creation." into rvc-dev
diff --git a/services/inputflinger/InputManager.cpp b/services/inputflinger/InputManager.cpp
index fc771a2..e68946d 100644
--- a/services/inputflinger/InputManager.cpp
+++ b/services/inputflinger/InputManager.cpp
@@ -111,8 +111,10 @@
handlesPerDisplay.emplace(info.displayId, std::vector<sp<InputWindowHandle>>());
handlesPerDisplay[info.displayId].push_back(new BinderWindowHandle(info));
}
- for (auto const& i : handlesPerDisplay) {
- mDispatcher->setInputWindows(i.second, i.first, setInputWindowsListener);
+ mDispatcher->setInputWindows(handlesPerDisplay);
+
+ if (setInputWindowsListener) {
+ setInputWindowsListener->onSetInputWindowsFinished();
}
}
diff --git a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
index 3b18813..7c5c9c5 100644
--- a/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
+++ b/services/inputflinger/benchmarks/InputDispatcher_benchmarks.cpp
@@ -252,7 +252,7 @@
sp<FakeApplicationHandle> application = new FakeApplicationHandle();
sp<FakeWindowHandle> window = new FakeWindowHandle(application, dispatcher, "Fake Window");
- dispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ dispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
NotifyMotionArgs motionArgs = generateMotionArgs();
@@ -288,7 +288,7 @@
sp<FakeApplicationHandle> application = new FakeApplicationHandle();
sp<FakeWindowHandle> window = new FakeWindowHandle(application, dispatcher, "Fake Window");
- dispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ dispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
for (auto _ : state) {
MotionEvent event = generateMotionEvent();
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index 308d19b..4ec61b0 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -3621,6 +3621,18 @@
mWindowHandlesByDisplay[displayId] = newHandles;
}
+void InputDispatcher::setInputWindows(
+ const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>& handlesPerDisplay) {
+ { // acquire lock
+ std::scoped_lock _l(mLock);
+ for (auto const& i : handlesPerDisplay) {
+ setInputWindowsLocked(i.second, i.first);
+ }
+ }
+ // Wake up poll loop since it may need to make new input dispatching choices.
+ mLooper->wake();
+}
+
/**
* Called from InputManagerService, update window handle list by displayId that can receive input.
* A window handle contains information about InputChannel, Touch Region, Types, Focused,...
@@ -3628,9 +3640,8 @@
* For focused handle, check if need to change and send a cancel event to previous one.
* For removed handle, check if need to send a cancel event if already in touch.
*/
-void InputDispatcher::setInputWindows(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
- int32_t displayId,
- const sp<ISetInputWindowsListener>& setInputWindowsListener) {
+void InputDispatcher::setInputWindowsLocked(
+ const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId) {
if (DEBUG_FOCUS) {
std::string windowList;
for (const sp<InputWindowHandle>& iwh : inputWindowHandles) {
@@ -3638,109 +3649,97 @@
}
ALOGD("setInputWindows displayId=%" PRId32 " %s", displayId, windowList.c_str());
}
- { // acquire lock
- std::scoped_lock _l(mLock);
- // Copy old handles for release if they are no longer present.
- const std::vector<sp<InputWindowHandle>> oldWindowHandles =
- getWindowHandlesLocked(displayId);
+ // Copy old handles for release if they are no longer present.
+ const std::vector<sp<InputWindowHandle>> oldWindowHandles = getWindowHandlesLocked(displayId);
- updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
+ updateWindowHandlesForDisplayLocked(inputWindowHandles, displayId);
- sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
- bool foundHoveredWindow = false;
- for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
- // Set newFocusedWindowHandle to the top most focused window instead of the last one
- if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
- windowHandle->getInfo()->visible) {
- newFocusedWindowHandle = windowHandle;
+ sp<InputWindowHandle> newFocusedWindowHandle = nullptr;
+ bool foundHoveredWindow = false;
+ for (const sp<InputWindowHandle>& windowHandle : getWindowHandlesLocked(displayId)) {
+ // Set newFocusedWindowHandle to the top most focused window instead of the last one
+ if (!newFocusedWindowHandle && windowHandle->getInfo()->hasFocus &&
+ windowHandle->getInfo()->visible) {
+ newFocusedWindowHandle = windowHandle;
+ }
+ if (windowHandle == mLastHoverWindowHandle) {
+ foundHoveredWindow = true;
+ }
+ }
+
+ if (!foundHoveredWindow) {
+ mLastHoverWindowHandle = nullptr;
+ }
+
+ sp<InputWindowHandle> oldFocusedWindowHandle =
+ getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
+
+ if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
+ if (oldFocusedWindowHandle != nullptr) {
+ if (DEBUG_FOCUS) {
+ ALOGD("Focus left window: %s in display %" PRId32,
+ oldFocusedWindowHandle->getName().c_str(), displayId);
}
- if (windowHandle == mLastHoverWindowHandle) {
- foundHoveredWindow = true;
+ sp<InputChannel> focusedInputChannel =
+ getInputChannelLocked(oldFocusedWindowHandle->getToken());
+ if (focusedInputChannel != nullptr) {
+ CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
+ "focus left window");
+ synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
+ enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
}
+ mFocusedWindowHandlesByDisplay.erase(displayId);
+ }
+ if (newFocusedWindowHandle != nullptr) {
+ if (DEBUG_FOCUS) {
+ ALOGD("Focus entered window: %s in display %" PRId32,
+ newFocusedWindowHandle->getName().c_str(), displayId);
+ }
+ mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
+ enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
}
- if (!foundHoveredWindow) {
- mLastHoverWindowHandle = nullptr;
+ if (mFocusedDisplayId == displayId) {
+ onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
}
+ }
- sp<InputWindowHandle> oldFocusedWindowHandle =
- getValueByKey(mFocusedWindowHandlesByDisplay, displayId);
-
- if (!haveSameToken(oldFocusedWindowHandle, newFocusedWindowHandle)) {
- if (oldFocusedWindowHandle != nullptr) {
+ ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
+ if (stateIndex >= 0) {
+ TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
+ for (size_t i = 0; i < state.windows.size();) {
+ TouchedWindow& touchedWindow = state.windows[i];
+ if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
if (DEBUG_FOCUS) {
- ALOGD("Focus left window: %s in display %" PRId32,
- oldFocusedWindowHandle->getName().c_str(), displayId);
+ ALOGD("Touched window was removed: %s in display %" PRId32,
+ touchedWindow.windowHandle->getName().c_str(), displayId);
}
- sp<InputChannel> focusedInputChannel =
- getInputChannelLocked(oldFocusedWindowHandle->getToken());
- if (focusedInputChannel != nullptr) {
- CancelationOptions options(CancelationOptions::CANCEL_NON_POINTER_EVENTS,
- "focus left window");
- synthesizeCancelationEventsForInputChannelLocked(focusedInputChannel, options);
- enqueueFocusEventLocked(*oldFocusedWindowHandle, false /*hasFocus*/);
+ sp<InputChannel> touchedInputChannel =
+ getInputChannelLocked(touchedWindow.windowHandle->getToken());
+ if (touchedInputChannel != nullptr) {
+ CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
+ "touched window was removed");
+ synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel, options);
}
- mFocusedWindowHandlesByDisplay.erase(displayId);
- }
- if (newFocusedWindowHandle != nullptr) {
- if (DEBUG_FOCUS) {
- ALOGD("Focus entered window: %s in display %" PRId32,
- newFocusedWindowHandle->getName().c_str(), displayId);
- }
- mFocusedWindowHandlesByDisplay[displayId] = newFocusedWindowHandle;
- enqueueFocusEventLocked(*newFocusedWindowHandle, true /*hasFocus*/);
- }
-
- if (mFocusedDisplayId == displayId) {
- onFocusChangedLocked(oldFocusedWindowHandle, newFocusedWindowHandle);
+ state.windows.erase(state.windows.begin() + i);
+ } else {
+ ++i;
}
}
+ }
- ssize_t stateIndex = mTouchStatesByDisplay.indexOfKey(displayId);
- if (stateIndex >= 0) {
- TouchState& state = mTouchStatesByDisplay.editValueAt(stateIndex);
- for (size_t i = 0; i < state.windows.size();) {
- TouchedWindow& touchedWindow = state.windows[i];
- if (!hasWindowHandleLocked(touchedWindow.windowHandle)) {
- if (DEBUG_FOCUS) {
- ALOGD("Touched window was removed: %s in display %" PRId32,
- touchedWindow.windowHandle->getName().c_str(), displayId);
- }
- sp<InputChannel> touchedInputChannel =
- getInputChannelLocked(touchedWindow.windowHandle->getToken());
- if (touchedInputChannel != nullptr) {
- CancelationOptions options(CancelationOptions::CANCEL_POINTER_EVENTS,
- "touched window was removed");
- synthesizeCancelationEventsForInputChannelLocked(touchedInputChannel,
- options);
- }
- state.windows.erase(state.windows.begin() + i);
- } else {
- ++i;
- }
+ // Release information for windows that are no longer present.
+ // This ensures that unused input channels are released promptly.
+ // Otherwise, they might stick around until the window handle is destroyed
+ // which might not happen until the next GC.
+ for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
+ if (!hasWindowHandleLocked(oldWindowHandle)) {
+ if (DEBUG_FOCUS) {
+ ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
}
+ oldWindowHandle->releaseChannel();
}
-
- // Release information for windows that are no longer present.
- // This ensures that unused input channels are released promptly.
- // Otherwise, they might stick around until the window handle is destroyed
- // which might not happen until the next GC.
- for (const sp<InputWindowHandle>& oldWindowHandle : oldWindowHandles) {
- if (!hasWindowHandleLocked(oldWindowHandle)) {
- if (DEBUG_FOCUS) {
- ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
- }
- oldWindowHandle->releaseChannel();
- }
- }
- } // release lock
-
- // Wake up poll loop since it may need to make new input dispatching choices.
- mLooper->wake();
-
- if (setInputWindowsListener) {
- setInputWindowsListener->onSetInputWindowsFinished();
}
}
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index 4aa47f8..cbba7e1 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -109,8 +109,8 @@
virtual std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) override;
virtual void setInputWindows(
- const std::vector<sp<InputWindowHandle>>& inputWindowHandles, int32_t displayId,
- const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) override;
+ const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
+ handlesPerDisplay) override;
virtual void setFocusedApplication(
int32_t displayId, const sp<InputApplicationHandle>& inputApplicationHandle) override;
virtual void setFocusedDisplay(int32_t displayId) override;
@@ -278,6 +278,8 @@
std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>> mWindowHandlesByDisplay
GUARDED_BY(mLock);
+ void setInputWindowsLocked(const std::vector<sp<InputWindowHandle>>& inputWindowHandles,
+ int32_t displayId) REQUIRES(mLock);
// Get window handles by display, return an empty vector if not found.
std::vector<sp<InputWindowHandle>> getWindowHandlesLocked(int32_t displayId) const
REQUIRES(mLock);
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 6e98676..09dc92c 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -19,6 +19,7 @@
#include <InputListener.h>
#include <input/ISetInputWindowsListener.h>
+#include <unordered_map>
namespace android {
@@ -99,13 +100,13 @@
*/
virtual std::unique_ptr<VerifiedInputEvent> verifyInputEvent(const InputEvent& event) = 0;
- /* Sets the list of input windows.
+ /* Sets the list of input windows per display.
*
* This method may be called on any thread (usually by the input manager).
*/
virtual void setInputWindows(
- const std::vector<sp<InputWindowHandle> >& inputWindowHandles, int32_t displayId,
- const sp<ISetInputWindowsListener>& setInputWindowsListener = nullptr) = 0;
+ const std::unordered_map<int32_t, std::vector<sp<InputWindowHandle>>>&
+ handlesPerDisplay) = 0;
/* Sets the focused application on the given display.
*
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 1f283b1..29f3dac 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -871,7 +871,7 @@
sp<FakeWindowHandle> window = new FakeWindowHandle(application, mDispatcher, "Fake Window",
ADISPLAY_ID_DEFAULT);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
<< "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
@@ -888,7 +888,7 @@
sp<FakeWindowHandle> windowSecond = new FakeWindowHandle(application, mDispatcher, "Second",
ADISPLAY_ID_DEFAULT);
- mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectMotionDown(mDispatcher,
AINPUT_SOURCE_TOUCHSCREEN, ADISPLAY_ID_DEFAULT))
<< "Inject motion event should return INPUT_EVENT_INJECTION_SUCCEEDED";
@@ -910,7 +910,7 @@
// Display should have only one focused window
windowSecond->setFocus(true);
- mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
windowSecond->consumeFocusEvent(true);
ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
@@ -935,7 +935,7 @@
windowTop->setFocus(true);
windowSecond->setFocus(true);
- mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
windowTop->consumeFocusEvent(true);
ASSERT_EQ(INPUT_EVENT_INJECTION_SUCCEEDED, injectKeyDown(mDispatcher))
<< "Inject key event should return INPUT_EVENT_INJECTION_SUCCEEDED";
@@ -960,7 +960,7 @@
windowSecond->setFocus(true);
// Release channel for window is no longer valid.
windowTop->releaseChannel();
- mDispatcher->setInputWindows({windowTop, windowSecond}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowTop, windowSecond}}});
windowSecond->consumeFocusEvent(true);
// Test inject a key down, should dispatch to a valid window.
@@ -986,7 +986,7 @@
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
- mDispatcher->setInputWindows({windowLeft, windowRight}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowLeft, windowRight}}});
// Inject an event with coordinate in the area of right window, with mouse cursor in the area of
// left window. This event should be dispatched to the left window.
@@ -1003,7 +1003,7 @@
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
window->setFocus(true);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
window->consumeFocusEvent(true);
NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
@@ -1025,7 +1025,7 @@
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
NotifyMotionArgs motionArgs =
generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -1053,7 +1053,7 @@
"Second Window", ADISPLAY_ID_DEFAULT);
// Add the windows to the dispatcher
- mDispatcher->setInputWindows({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
// Send down to the first window
NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
@@ -1090,7 +1090,7 @@
"Second Window", ADISPLAY_ID_DEFAULT);
// Add the windows to the dispatcher
- mDispatcher->setInputWindows({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
// Send down to the first window
NotifyMotionArgs downMotionArgs = generateMotionArgs(AMOTION_EVENT_ACTION_DOWN,
@@ -1152,7 +1152,7 @@
| InputWindowInfo::FLAG_SPLIT_TOUCH);
// Add the windows to the dispatcher
- mDispatcher->setInputWindows({firstWindow, secondWindow}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {firstWindow, secondWindow}}});
PointF pointInFirst = {300, 200};
PointF pointInSecond = {300, 600};
@@ -1204,7 +1204,7 @@
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
window->setFocus(true);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
window->consumeFocusEvent(true);
@@ -1220,7 +1220,7 @@
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
mDispatcher->notifyKey(&keyArgs);
@@ -1235,7 +1235,7 @@
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
// Send key
NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN, ADISPLAY_ID_DEFAULT);
@@ -1289,7 +1289,7 @@
sp<FakeApplicationHandle> application = new FakeApplicationHandle();
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
true /*isGestureMonitor*/);
@@ -1309,7 +1309,7 @@
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
window->setFocus(true);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
window->consumeFocusEvent(true);
FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
@@ -1325,7 +1325,7 @@
sp<FakeApplicationHandle> application = new FakeApplicationHandle();
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
FakeMonitorReceiver monitor = FakeMonitorReceiver(mDispatcher, "GM_1", ADISPLAY_ID_DEFAULT,
true /*isGestureMonitor*/);
@@ -1351,7 +1351,7 @@
sp<FakeWindowHandle> window =
new FakeWindowHandle(application, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
NotifyMotionArgs motionArgs =
generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -1387,29 +1387,29 @@
window->setFocus(true);
SCOPED_TRACE("Check default value of touch mode");
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
SCOPED_TRACE("Remove the window to trigger focus loss");
window->setFocus(false);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
window->consumeFocusEvent(false /*hasFocus*/, true /*inTouchMode*/);
SCOPED_TRACE("Disable touch mode");
mDispatcher->setInTouchMode(false);
window->setFocus(true);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
window->consumeFocusEvent(true /*hasFocus*/, false /*inTouchMode*/);
SCOPED_TRACE("Remove the window to trigger focus loss");
window->setFocus(false);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
window->consumeFocusEvent(false /*hasFocus*/, false /*inTouchMode*/);
SCOPED_TRACE("Enable touch mode again");
mDispatcher->setInTouchMode(true);
window->setFocus(true);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
window->assertNoEvents();
@@ -1423,7 +1423,7 @@
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
window->setFocus(true);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
window->consumeFocusEvent(true /*hasFocus*/, true /*inTouchMode*/);
NotifyKeyArgs keyArgs = generateKeyArgs(AKEY_EVENT_ACTION_DOWN);
@@ -1459,7 +1459,7 @@
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application);
- mDispatcher->setInputWindows({window}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {window}}});
NotifyMotionArgs motionArgs =
generateMotionArgs(AMOTION_EVENT_ACTION_DOWN, AINPUT_SOURCE_TOUCHSCREEN,
@@ -1512,7 +1512,7 @@
mWindow = new FakeWindowHandle(mApp, mDispatcher, "Fake Window", ADISPLAY_ID_DEFAULT);
mWindow->setFocus(true);
- mDispatcher->setInputWindows({mWindow}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow}}});
mWindow->consumeFocusEvent(true);
}
@@ -1602,7 +1602,7 @@
// Set focus window for primary display, but focused display would be second one.
mDispatcher->setFocusedApplication(ADISPLAY_ID_DEFAULT, application1);
windowInPrimary->setFocus(true);
- mDispatcher->setInputWindows({windowInPrimary}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {windowInPrimary}}});
windowInPrimary->consumeFocusEvent(true);
application2 = new FakeApplicationHandle();
@@ -1614,7 +1614,7 @@
// Set focus window for second display.
mDispatcher->setFocusedApplication(SECOND_DISPLAY_ID, application2);
windowInSecondary->setFocus(true);
- mDispatcher->setInputWindows({windowInSecondary}, SECOND_DISPLAY_ID);
+ mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {windowInSecondary}}});
windowInSecondary->consumeFocusEvent(true);
}
@@ -1664,7 +1664,7 @@
windowInSecondary->consumeKeyDown(ADISPLAY_ID_NONE);
// Remove all windows in secondary display.
- mDispatcher->setInputWindows({}, SECOND_DISPLAY_ID);
+ mDispatcher->setInputWindows({{SECOND_DISPLAY_ID, {}}});
// Expect old focus should receive a cancel event.
windowInSecondary->consumeEvent(AINPUT_EVENT_TYPE_KEY, AKEY_EVENT_ACTION_UP, ADISPLAY_ID_NONE,
@@ -1828,7 +1828,7 @@
mFocusedWindow->setFocus(true);
// Expect one focus window exist in display.
- mDispatcher->setInputWindows({mUnfocusedWindow, mFocusedWindow}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mUnfocusedWindow, mFocusedWindow}}});
mFocusedWindow->consumeFocusEvent(true);
}
@@ -1916,7 +1916,7 @@
mWindow2->setId(1);
mWindow2->setFrame(Rect(100, 100, 200, 200));
- mDispatcher->setInputWindows({mWindow1, mWindow2}, ADISPLAY_ID_DEFAULT);
+ mDispatcher->setInputWindows({{ADISPLAY_ID_DEFAULT, {mWindow1, mWindow2}}});
}
protected:
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index 9a13c00..77d8c11 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <cinttypes>
#include <sys/socket.h>
#include <utils/threads.h>
@@ -69,17 +70,17 @@
}
bool SensorService::SensorEventConnection::needsWakeLock() {
- Mutex::Autolock _l(mConnectionLock);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
return !mDead && mWakeLockRefCount > 0;
}
void SensorService::SensorEventConnection::resetWakeLockRefCount() {
- Mutex::Autolock _l(mConnectionLock);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
mWakeLockRefCount = 0;
}
void SensorService::SensorEventConnection::dump(String8& result) {
- Mutex::Autolock _l(mConnectionLock);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
result.appendFormat("\tOperating Mode: ");
if (!mService->isWhiteListedPackage(getPackageName())) {
result.append("RESTRICTED\n");
@@ -91,11 +92,11 @@
result.appendFormat("\t %s | WakeLockRefCount %d | uid %d | cache size %d | "
"max cache size %d\n", mPackageName.string(), mWakeLockRefCount, mUid, mCacheSize,
mMaxCacheSize);
- for (size_t i = 0; i < mSensorInfo.size(); ++i) {
- const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
+ for (auto& it : mSensorInfo) {
+ const FlushInfo& flushInfo = it.second.flushInfo;
result.appendFormat("\t %s 0x%08x | status: %s | pending flush events %d \n",
- mService->getSensorName(mSensorInfo.keyAt(i)).string(),
- mSensorInfo.keyAt(i),
+ mService->getSensorName(it.first).string(),
+ it.first,
flushInfo.mFirstFlushPending ? "First flush pending" :
"active",
flushInfo.mPendingFlushEventsToSend);
@@ -121,7 +122,7 @@
*/
void SensorService::SensorEventConnection::dump(util::ProtoOutputStream* proto) const {
using namespace service::SensorEventConnectionProto;
- Mutex::Autolock _l(mConnectionLock);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
if (!mService->isWhiteListedPackage(getPackageName())) {
proto->write(OPERATING_MODE, OP_MODE_RESTRICTED);
@@ -135,12 +136,12 @@
proto->write(UID, int32_t(mUid));
proto->write(CACHE_SIZE, int32_t(mCacheSize));
proto->write(MAX_CACHE_SIZE, int32_t(mMaxCacheSize));
- for (size_t i = 0; i < mSensorInfo.size(); ++i) {
- const FlushInfo& flushInfo = mSensorInfo.valueAt(i);
+ for (auto& it : mSensorInfo) {
+ const FlushInfo& flushInfo = it.second.flushInfo;
const uint64_t token = proto->start(FLUSH_INFOS);
proto->write(FlushInfoProto::SENSOR_NAME,
- std::string(mService->getSensorName(mSensorInfo.keyAt(i))));
- proto->write(FlushInfoProto::SENSOR_HANDLE, mSensorInfo.keyAt(i));
+ std::string(mService->getSensorName(it.first)));
+ proto->write(FlushInfoProto::SENSOR_HANDLE, it.first);
proto->write(FlushInfoProto::FIRST_FLUSH_PENDING, flushInfo.mFirstFlushPending);
proto->write(FlushInfoProto::PENDING_FLUSH_EVENTS_TO_SEND,
flushInfo.mPendingFlushEventsToSend);
@@ -157,40 +158,54 @@
#endif
}
-bool SensorService::SensorEventConnection::addSensor(int32_t handle) {
- Mutex::Autolock _l(mConnectionLock);
+bool SensorService::SensorEventConnection::addSensor(
+ int32_t handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags) {
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
if (si == nullptr ||
!canAccessSensor(si->getSensor(), "Tried adding", mOpPackageName) ||
- mSensorInfo.indexOfKey(handle) >= 0) {
+ mSensorInfo.count(handle) > 0) {
return false;
}
- mSensorInfo.add(handle, FlushInfo());
+
+ SensorRequest request = {
+ .samplingPeriodNs = samplingPeriodNs,
+ .maxBatchReportLatencyNs = maxBatchReportLatencyNs,
+ .reservedFlags = reservedFlags
+ };
+
+ mSensorInfo[handle] = request;
return true;
}
bool SensorService::SensorEventConnection::removeSensor(int32_t handle) {
- Mutex::Autolock _l(mConnectionLock);
- if (mSensorInfo.removeItem(handle) >= 0) {
- return true;
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+ return mSensorInfo.erase(handle) > 0;
+}
+
+std::vector<int32_t> SensorService::SensorEventConnection::getActiveSensorHandles() const {
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+ std::vector<int32_t> list;
+ for (auto& it : mSensorInfo) {
+ list.push_back(it.first);
}
- return false;
+ return list;
}
bool SensorService::SensorEventConnection::hasSensor(int32_t handle) const {
- Mutex::Autolock _l(mConnectionLock);
- return mSensorInfo.indexOfKey(handle) >= 0;
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+ return mSensorInfo.count(handle) + mSensorInfoBackup.count(handle) > 0;
}
bool SensorService::SensorEventConnection::hasAnySensor() const {
- Mutex::Autolock _l(mConnectionLock);
- return mSensorInfo.size() ? true : false;
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+ return mSensorInfo.size() + mSensorInfoBackup.size() ? true : false;
}
bool SensorService::SensorEventConnection::hasOneShotSensors() const {
- Mutex::Autolock _l(mConnectionLock);
- for (size_t i = 0; i < mSensorInfo.size(); ++i) {
- const int handle = mSensorInfo.keyAt(i);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+ for (auto &it : mSensorInfo) {
+ const int handle = it.first;
sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
if (si != nullptr && si->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
return true;
@@ -205,16 +220,15 @@
void SensorService::SensorEventConnection::setFirstFlushPending(int32_t handle,
bool value) {
- Mutex::Autolock _l(mConnectionLock);
- ssize_t index = mSensorInfo.indexOfKey(handle);
- if (index >= 0) {
- FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+ if (mSensorInfo.count(handle) > 0) {
+ FlushInfo& flushInfo = mSensorInfo[handle].flushInfo;
flushInfo.mFirstFlushPending = value;
}
}
void SensorService::SensorEventConnection::updateLooperRegistration(const sp<Looper>& looper) {
- Mutex::Autolock _l(mConnectionLock);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
updateLooperRegistrationLocked(looper);
}
@@ -233,8 +247,8 @@
int looper_flags = 0;
if (mCacheSize > 0) looper_flags |= ALOOPER_EVENT_OUTPUT;
if (mDataInjectionMode) looper_flags |= ALOOPER_EVENT_INPUT;
- for (size_t i = 0; i < mSensorInfo.size(); ++i) {
- const int handle = mSensorInfo.keyAt(i);
+ for (auto& it : mSensorInfo) {
+ const int handle = it.first;
sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
if (si != nullptr && si->getSensor().isWakeUpSensor()) {
looper_flags |= ALOOPER_EVENT_INPUT;
@@ -265,10 +279,9 @@
}
void SensorService::SensorEventConnection::incrementPendingFlushCount(int32_t handle) {
- Mutex::Autolock _l(mConnectionLock);
- ssize_t index = mSensorInfo.indexOfKey(handle);
- if (index >= 0) {
- FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+ if (mSensorInfo.count(handle) > 0) {
+ FlushInfo& flushInfo = mSensorInfo[handle].flushInfo;
flushInfo.mPendingFlushEventsToSend++;
}
}
@@ -282,7 +295,7 @@
std::unique_ptr<sensors_event_t[]> sanitizedBuffer;
int count = 0;
- Mutex::Autolock _l(mConnectionLock);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
if (scratch) {
size_t i=0;
while (i<numEvents) {
@@ -296,15 +309,14 @@
sensor_handle = buffer[i].meta_data.sensor;
}
- ssize_t index = mSensorInfo.indexOfKey(sensor_handle);
// Check if this connection has registered for this sensor. If not continue to the
// next sensor_event.
- if (index < 0) {
+ if (mSensorInfo.count(sensor_handle) == 0) {
++i;
continue;
}
- FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+ FlushInfo& flushInfo = mSensorInfo[sensor_handle].flushInfo;
// Check if there is a pending flush_complete event for this sensor on this connection.
if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
mapFlushEventsToConnections[i] == this) {
@@ -425,9 +437,55 @@
return size < 0 ? status_t(size) : status_t(NO_ERROR);
}
+void SensorService::SensorEventConnection::updateSensorSubscriptions() {
+ if (!hasSensorAccess()) {
+ stopAll();
+ } else {
+ recoverAll();
+ }
+}
+
void SensorService::SensorEventConnection::setSensorAccess(const bool hasAccess) {
- Mutex::Autolock _l(mConnectionLock);
- mHasSensorAccess = hasAccess;
+ if (mHasSensorAccess != hasAccess) {
+ mHasSensorAccess = hasAccess;
+ updateSensorSubscriptions();
+ }
+}
+
+void SensorService::SensorEventConnection::stopAll() {
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+ if (!mSensorInfo.empty()) {
+ mSensorInfoBackup = mSensorInfo;
+ mSensorInfo.clear();
+
+ for (auto& it : mSensorInfoBackup) {
+ int32_t handle = it.first;
+
+ status_t err = mService->disable(this, handle);
+
+ if (err != NO_ERROR) {
+ ALOGE("Error disabling sensor %d", handle);
+ }
+ }
+ }
+}
+
+void SensorService::SensorEventConnection::recoverAll() {
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+ for (auto& it : mSensorInfoBackup) {
+ int32_t handle = it.first;
+ SensorRequest &request = it.second;
+
+ status_t err = mService->enable(
+ this, handle, request.samplingPeriodNs, request.maxBatchReportLatencyNs,
+ request.reservedFlags, mOpPackageName);
+
+ if (err != NO_ERROR) {
+ ALOGE("Error recovering sensor %d", handle);
+ }
+ }
+
+ mSensorInfoBackup.clear();
}
bool SensorService::SensorEventConnection::hasSensorAccess() {
@@ -522,14 +580,14 @@
flushCompleteEvent.type = SENSOR_TYPE_META_DATA;
// Loop through all the sensors for this connection and check if there are any pending
// flush complete events to be sent.
- for (size_t i = 0; i < mSensorInfo.size(); ++i) {
- const int handle = mSensorInfo.keyAt(i);
+ for (auto& it : mSensorInfo) {
+ const int handle = it.first;
sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(handle);
if (si == nullptr) {
continue;
}
- FlushInfo& flushInfo = mSensorInfo.editValueAt(i);
+ FlushInfo& flushInfo = it.second.flushInfo;
while (flushInfo.mPendingFlushEventsToSend > 0) {
flushCompleteEvent.meta_data.sensor = handle;
bool wakeUpSensor = si->getSensor().isWakeUpSensor();
@@ -554,7 +612,7 @@
// half the size of the socket buffer allocated in BitTube whichever is smaller.
const int maxWriteSize = helpers::min(SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT/2,
int(mService->mSocketBufferSize/(sizeof(sensors_event_t)*2)));
- Mutex::Autolock _l(mConnectionLock);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
// Send pending flush complete events (if any)
sendPendingFlushEventsLocked();
for (int numEventsSent = 0; numEventsSent < mCacheSize;) {
@@ -615,14 +673,13 @@
// separately before the next batch of events.
for (int j = 0; j < numEventsDropped; ++j) {
if (scratch[j].type == SENSOR_TYPE_META_DATA) {
- ssize_t index = mSensorInfo.indexOfKey(scratch[j].meta_data.sensor);
- if (index < 0) {
+ if (mSensorInfo.count(scratch[j].meta_data.sensor) == 0) {
ALOGW("%s: sensor 0x%x is not found in connection",
__func__, scratch[j].meta_data.sensor);
continue;
}
- FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
+ FlushInfo& flushInfo = mSensorInfo[scratch[j].meta_data.sensor].flushInfo;
flushInfo.mPendingFlushEventsToSend++;
ALOGD_IF(DEBUG_CONNECTIONS, "increment pendingFlushCount %d",
flushInfo.mPendingFlushEventsToSend);
@@ -658,13 +715,21 @@
} else {
err = mService->disable(this, handle);
}
+
return err;
}
status_t SensorService::SensorEventConnection::setEventRate(
int handle, nsecs_t samplingPeriodNs)
{
- return mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
+ status_t err = mService->setEventRate(this, handle, samplingPeriodNs, mOpPackageName);
+
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
+ if (err == NO_ERROR && mSensorInfo.count(handle) > 0) {
+ mSensorInfo[handle].samplingPeriodNs = samplingPeriodNs;
+ }
+
+ return err;
}
status_t SensorService::SensorEventConnection::flush() {
@@ -685,7 +750,7 @@
// and remove the fd from Looper. Call checkWakeLockState to know if SensorService
// can release the wake-lock.
ALOGD_IF(DEBUG_CONNECTIONS, "%p Looper error %d", this, fd);
- Mutex::Autolock _l(mConnectionLock);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
mDead = true;
mWakeLockRefCount = 0;
updateLooperRegistrationLocked(mService->getLooper());
@@ -704,7 +769,7 @@
unsigned char buf[sizeof(sensors_event_t)];
ssize_t numBytesRead = ::recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
{
- Mutex::Autolock _l(mConnectionLock);
+ std::lock_guard<std::recursive_mutex> _l(mConnectionLock);
if (numBytesRead == sizeof(sensors_event_t)) {
if (!mDataInjectionMode) {
ALOGE("Data injected in normal mode, dropping event"
@@ -764,8 +829,8 @@
int SensorService::SensorEventConnection::computeMaxCacheSizeLocked() const {
size_t fifoWakeUpSensors = 0;
size_t fifoNonWakeUpSensors = 0;
- for (size_t i = 0; i < mSensorInfo.size(); ++i) {
- sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(mSensorInfo.keyAt(i));
+ for (auto& it : mSensorInfo) {
+ sp<SensorInterface> si = mService->getSensorInterfaceFromHandle(it.first);
if (si == nullptr) {
continue;
}
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index caf5d7c..3ba5c07 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -23,7 +23,6 @@
#include <utils/Vector.h>
#include <utils/SortedVector.h>
-#include <utils/KeyedVector.h>
#include <utils/threads.h>
#include <utils/AndroidThreads.h>
#include <utils/RefBase.h>
@@ -58,8 +57,10 @@
bool hasSensor(int32_t handle) const;
bool hasAnySensor() const;
bool hasOneShotSensors() const;
- bool addSensor(int32_t handle);
+ bool addSensor(
+ int32_t handle, nsecs_t samplingPeriodNs, nsecs_t maxBatchReportLatencyNs, int reservedFlags);
bool removeSensor(int32_t handle);
+ std::vector<int32_t> getActiveSensorHandles() const;
void setFirstFlushPending(int32_t handle, bool value);
void dump(String8& result);
void dump(util::ProtoOutputStream* proto) const;
@@ -70,7 +71,7 @@
uid_t getUid() const { return mUid; }
void setSensorAccess(const bool hasAccess);
-
+ void updateSensorSubscriptions();
private:
virtual ~SensorEventConnection();
virtual void onFirstRef();
@@ -136,13 +137,16 @@
// privacy not being enabled.
bool hasSensorAccess();
+ void stopAll();
+ void recoverAll();
+
// Call noteOp for the sensor if the sensor requires a permission
bool noteOpIfRequired(const sensors_event_t& event);
sp<SensorService> const mService;
sp<BitTube> mChannel;
uid_t mUid;
- mutable Mutex mConnectionLock;
+ mutable std::recursive_mutex mConnectionLock;
// Number of events from wake up sensors which are still pending and haven't been delivered to
// the corresponding application. It is incremented by one unit for each write to the socket.
uint32_t mWakeLockRefCount;
@@ -169,8 +173,17 @@
FlushInfo() : mPendingFlushEventsToSend(0), mFirstFlushPending(false) {}
};
- // protected by SensorService::mLock. Key for this vector is the sensor handle.
- KeyedVector<int, FlushInfo> mSensorInfo;
+
+ struct SensorRequest {
+ nsecs_t samplingPeriodNs;
+ nsecs_t maxBatchReportLatencyNs;
+ int reservedFlags;
+ FlushInfo flushInfo;
+ };
+
+ // protected by SensorService::mLock. Key for this map is the sensor handle.
+ std::unordered_map<int32_t, SensorRequest> mSensorInfo;
+ std::unordered_map<int32_t, SensorRequest> mSensorInfoBackup;
sensors_event_t *mEventCache;
int mCacheSize, mMaxCacheSize;
@@ -185,7 +198,7 @@
mutable Mutex mDestroyLock;
bool mDestroyed;
- bool mHasSensorAccess;
+ std::atomic_bool mHasSensorAccess;
// Store a mapping of sensor handles to required AppOp for a sensor. This map only contains a
// valid mapping for sensors that require a permission in order to reduce the lookup time.
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 22a15c6..5ae7c51 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -301,7 +301,10 @@
void SensorService::setSensorAccess(uid_t uid, bool hasAccess) {
ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock);
- for (const sp<SensorEventConnection>& conn : connLock.getActiveConnections()) {
+ const auto& connections = connLock.getActiveConnections();
+
+ mLock.unlock();
+ for (const sp<SensorEventConnection>& conn : connections) {
if (conn->getUid() == uid) {
conn->setSensorAccess(hasAccess);
}
@@ -638,6 +641,9 @@
void SensorService::disableAllSensorsLocked(ConnectionSafeAutolock* connLock) {
SensorDevice& dev(SensorDevice::getInstance());
+ for (const sp<SensorEventConnection>& connection : connLock->getActiveConnections()) {
+ connection->updateSensorSubscriptions();
+ }
for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) {
connection->stopAll(true /* backupRecord */);
}
@@ -666,6 +672,9 @@
}
SensorDevice& dev(SensorDevice::getInstance());
dev.enableAllSensors();
+ for (const sp<SensorEventConnection>& connection : connLock->getActiveConnections()) {
+ connection->updateSensorSubscriptions();
+ }
for (const sp<SensorDirectConnection>& connection : connLock->getDirectConnections()) {
connection->recoverAll();
}
@@ -1589,7 +1598,7 @@
}
}
- if (connection->addSensor(handle)) {
+ if (connection->addSensor(handle, samplingPeriodNs, maxBatchReportLatencyNs, reservedFlags)) {
BatteryService::enableSensor(connection->getUid(), handle);
// the sensor was added (which means it wasn't already there)
// so, see if this connection becomes active
@@ -1739,18 +1748,22 @@
const int halVersion = dev.getHalDeviceVersion();
status_t err(NO_ERROR);
Mutex::Autolock _l(mLock);
+
+ size_t numSensors = 0;
// Loop through all sensors for this connection and call flush on each of them.
- for (size_t i = 0; i < connection->mSensorInfo.size(); ++i) {
- const int handle = connection->mSensorInfo.keyAt(i);
+ for (int handle : connection->getActiveSensorHandles()) {
sp<SensorInterface> sensor = getSensorInterfaceFromHandle(handle);
if (sensor == nullptr) {
continue;
}
+ numSensors++;
+
if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
ALOGE("flush called on a one-shot sensor");
err = INVALID_OPERATION;
continue;
}
+
if (halVersion <= SENSORS_DEVICE_API_VERSION_1_0 || isVirtualSensor(handle)) {
// For older devices just increment pending flush count which will send a trivial
// flush complete event.
@@ -1768,7 +1781,8 @@
err = (err_flush != NO_ERROR) ? err_flush : err;
}
}
- return err;
+
+ return (numSensors == 0) ? INVALID_OPERATION : err;
}
bool SensorService::canAccessSensor(const Sensor& sensor, const char* operation,