Loading libs/binder/libbinder_rpc_unstable.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,13 @@ ARpcServer* ARpcServer_newInitUnixDomain(AIBinder* service, const char* name) { LOG(ERROR) << "Failed to get fd for the socket:" << name; return nullptr; } // Control socket fds are inherited from init, so they don't have O_CLOEXEC set. // But we don't want any child processes to inherit the socket we are running // the server on, so attempt to set the flag now. if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { LOG(WARNING) << "Failed to set CLOEXEC on control socket with name " << name << " error: " << errno; } if (status_t status = server->setupRawSocketServer(std::move(fd)); status != OK) { LOG(ERROR) << "Failed to set up Unix Domain RPC server with name " << name << " error: " << statusToString(status).c_str(); Loading services/inputflinger/reader/mapper/gestures/GestureConverter.cpp +8 −4 Original line number Diff line number Diff line Loading @@ -216,12 +216,16 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_ yCursorPosition)); } } // TODO(b/251196347): Set the gesture properties appropriately to avoid needing to negate the Y // values. float rotatedDeltaX = dx, rotatedDeltaY = -dy; rotateDelta(mOrientation, &rotatedDeltaX, &rotatedDeltaY); for (size_t i = 0; i < mSwipeFingerCount; i++) { PointerCoords& coords = mFakeFingerCoords[i]; coords.setAxisValue(AMOTION_EVENT_AXIS_X, coords.getAxisValue(AMOTION_EVENT_AXIS_X) + dx); // TODO(b/251196347): Set the gesture properties appropriately to avoid needing to negate // the Y values. coords.setAxisValue(AMOTION_EVENT_AXIS_Y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y) - dy); coords.setAxisValue(AMOTION_EVENT_AXIS_X, coords.getAxisValue(AMOTION_EVENT_AXIS_X) + rotatedDeltaX); coords.setAxisValue(AMOTION_EVENT_AXIS_Y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y) + rotatedDeltaY); } float xOffset = dx / (mXAxisInfo.maxValue - mXAxisInfo.minValue); // TODO(b/251196347): Set the gesture properties appropriately to avoid needing to negate the Y Loading services/inputflinger/tests/GestureConverter_test.cpp +77 −0 Original line number Diff line number Diff line Loading @@ -353,6 +353,83 @@ TEST_F(GestureConverterTest, ThreeFingerSwipe_Vertical) { WithPointerCount(1u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); } TEST_F(GestureConverterTest, ThreeFingerSwipe_Rotated) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); converter.setOrientation(ui::ROTATION_90); Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0, /* dy= */ 10); std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture); ASSERT_EQ(4u, args.size()); // Three fake fingers should be created. We don't actually care where they are, so long as they // move appropriately. NotifyMotionArgs arg = std::get<NotifyMotionArgs>(args.front()); ASSERT_THAT(arg, AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithGestureOffset(0, 0, EPSILON), WithPointerCount(1u))); PointerCoords finger0Start = arg.pointerCoords[0]; args.pop_front(); arg = std::get<NotifyMotionArgs>(args.front()); ASSERT_THAT(arg, AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u))); PointerCoords finger1Start = arg.pointerCoords[1]; args.pop_front(); arg = std::get<NotifyMotionArgs>(args.front()); ASSERT_THAT(arg, AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN | 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u))); PointerCoords finger2Start = arg.pointerCoords[2]; args.pop_front(); arg = std::get<NotifyMotionArgs>(args.front()); ASSERT_THAT(arg, AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithGestureOffset(0, -0.01, EPSILON), WithPointerCount(3u))); EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() - 10); EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() - 10); EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() - 10); EXPECT_EQ(arg.pointerCoords[0].getY(), finger0Start.getY()); EXPECT_EQ(arg.pointerCoords[1].getY(), finger1Start.getY()); EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY()); Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0, /* dy= */ 5); args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture); ASSERT_EQ(1u, args.size()); arg = std::get<NotifyMotionArgs>(args.front()); ASSERT_THAT(arg, AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithGestureOffset(0, -0.005, EPSILON), WithPointerCount(3u))); EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() - 15); EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() - 15); EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() - 15); EXPECT_EQ(arg.pointerCoords[0].getY(), finger0Start.getY()); EXPECT_EQ(arg.pointerCoords[1].getY(), finger1Start.getY()); EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY()); Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME); args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture); ASSERT_EQ(3u, args.size()); ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP | 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u))); args.pop_front(); ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u))); args.pop_front(); ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON), WithPointerCount(1u))); } TEST_F(GestureConverterTest, FourFingerSwipe_Horizontal) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); Loading services/sensorservice/SensorEventConnection.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -82,7 +82,7 @@ void SensorService::SensorEventConnection::resetWakeLockRefCount() { void SensorService::SensorEventConnection::dump(String8& result) { Mutex::Autolock _l(mConnectionLock); result.appendFormat("\tOperating Mode: "); if (!mService->isWhiteListedPackage(getPackageName())) { if (!mService->isAllowListedPackage(getPackageName())) { result.append("RESTRICTED\n"); } else if (mDataInjectionMode) { result.append("DATA_INJECTION\n"); Loading Loading @@ -124,7 +124,7 @@ void SensorService::SensorEventConnection::dump(util::ProtoOutputStream* proto) using namespace service::SensorEventConnectionProto; Mutex::Autolock _l(mConnectionLock); if (!mService->isWhiteListedPackage(getPackageName())) { if (!mService->isAllowListedPackage(getPackageName())) { proto->write(OPERATING_MODE, OP_MODE_RESTRICTED); } else if (mDataInjectionMode) { proto->write(OPERATING_MODE, OP_MODE_DATA_INJECTION); Loading Loading @@ -850,7 +850,7 @@ int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* // Unregister call backs. return 0; } if (!mService->isWhiteListedPackage(mPackageName)) { if (!mService->isAllowListedPackage(mPackageName)) { ALOGE("App not allowed to inject data, dropping event" "package=%s uid=%d", mPackageName.string(), mUid); return 0; Loading services/sensorservice/SensorService.cpp +114 −82 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ #include <ctime> #include <future> #include <string> #include <private/android_filesystem_config.h> Loading Loading @@ -548,80 +549,22 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { if (args.size() > 2) { return INVALID_OPERATION; } ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); SensorDevice& dev(SensorDevice::getInstance()); if (args.size() == 2 && args[0] == String16("restrict")) { // If already in restricted mode. Ignore. if (mCurrentOperatingMode == RESTRICTED) { return status_t(NO_ERROR); } // If in any mode other than normal, ignore. if (mCurrentOperatingMode != NORMAL) { return INVALID_OPERATION; } mCurrentOperatingMode = RESTRICTED; // temporarily stop all sensor direct report and disable sensors disableAllSensorsLocked(&connLock); mWhiteListedPackage.setTo(String8(args[1])); return status_t(NO_ERROR); } else if (args.size() == 1 && args[0] == String16("enable")) { // If currently in restricted mode, reset back to NORMAL mode else ignore. if (mCurrentOperatingMode == RESTRICTED) { mCurrentOperatingMode = NORMAL; // enable sensors and recover all sensor direct report enableAllSensorsLocked(&connLock); } if (mCurrentOperatingMode == REPLAY_DATA_INJECTION) { dev.disableAllSensors(); } if (mCurrentOperatingMode == DATA_INJECTION || mCurrentOperatingMode == REPLAY_DATA_INJECTION) { resetToNormalModeLocked(); } mWhiteListedPackage.clear(); return status_t(NO_ERROR); } else if (args.size() == 2 && args[0] == String16("data_injection")) { if (mCurrentOperatingMode == NORMAL) { dev.disableAllSensors(); status_t err = dev.setMode(DATA_INJECTION); if (err == NO_ERROR) { mCurrentOperatingMode = DATA_INJECTION; } else { // Re-enable sensors. dev.enableAllSensors(); if (args.size() > 0) { Mode targetOperatingMode = NORMAL; std::string inputStringMode = String8(args[0]).string(); if (getTargetOperatingMode(inputStringMode, &targetOperatingMode)) { status_t error = changeOperatingMode(args, targetOperatingMode); // Dump the latest state only if no error was encountered. if (error != NO_ERROR) { return error; } mWhiteListedPackage.setTo(String8(args[1])); return NO_ERROR; } else if (mCurrentOperatingMode == DATA_INJECTION) { // Already in DATA_INJECTION mode. Treat this as a no_op. return NO_ERROR; } else { // Transition to data injection mode supported only from NORMAL mode. return INVALID_OPERATION; } } else if (args.size() == 2 && args[0] == String16("replay_data_injection") && !SensorServiceUtil::isUserBuild()) { if (mCurrentOperatingMode == NORMAL) { dev.disableAllSensors(); // Use DATA_INJECTION here since this value goes to the HAL and the HAL doesn't // have an understanding of replay vs. normal data injection. status_t err = dev.setMode(DATA_INJECTION); if (err == NO_ERROR) { mCurrentOperatingMode = REPLAY_DATA_INJECTION; } // Re-enable sensors. dev.enableAllSensors(); mWhiteListedPackage.setTo(String8(args[1])); return NO_ERROR; } else if (mCurrentOperatingMode == REPLAY_DATA_INJECTION) { // Already in REPLAY_DATA_INJECTION mode. Treat this as a no_op. return NO_ERROR; } else { // Transition to data injection mode supported only from NORMAL mode. return INVALID_OPERATION; } } else if (args.size() == 1 && args[0] == String16("--proto")) { ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); // Run the following logic if a transition isn't requested above based on the input // argument parsing. if (args.size() == 1 && args[0] == String16("--proto")) { return dumpProtoLocked(fd, &connLock); } else if (!mSensors.hasAnySensor()) { result.append("No Sensors on the device\n"); Loading Loading @@ -680,14 +623,14 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { result.appendFormat(" NORMAL\n"); break; case RESTRICTED: result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string()); result.appendFormat(" RESTRICTED : %s\n", mAllowListedPackage.string()); break; case DATA_INJECTION: result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string()); result.appendFormat(" DATA_INJECTION : %s\n", mAllowListedPackage.string()); break; case REPLAY_DATA_INJECTION: result.appendFormat(" REPLAY_DATA_INJECTION : %s\n", mWhiteListedPackage.string()); mAllowListedPackage.string()); break; default: result.appendFormat(" UNKNOWN\n"); Loading Loading @@ -809,11 +752,11 @@ status_t SensorService::dumpProtoLocked(int fd, ConnectionSafeAutolock* connLock break; case RESTRICTED: proto.write(OPERATING_MODE, OP_MODE_RESTRICTED); proto.write(WHITELISTED_PACKAGE, std::string(mWhiteListedPackage.string())); proto.write(WHITELISTED_PACKAGE, std::string(mAllowListedPackage.string())); break; case DATA_INJECTION: proto.write(OPERATING_MODE, OP_MODE_DATA_INJECTION); proto.write(WHITELISTED_PACKAGE, std::string(mWhiteListedPackage.string())); proto.write(WHITELISTED_PACKAGE, std::string(mAllowListedPackage.string())); break; default: proto.write(OPERATING_MODE, OP_MODE_UNKNOWN); Loading Loading @@ -1545,7 +1488,7 @@ sp<ISensorEventConnection> SensorService::createSensorEventConnection(const Stri // operating in DI mode. if (requestedMode == DATA_INJECTION) { if (mCurrentOperatingMode != DATA_INJECTION) return nullptr; if (!isWhiteListedPackage(packageName)) return nullptr; if (!isAllowListedPackage(packageName)) return nullptr; } uid_t uid = IPCThreadState::self()->getCallingUid(); Loading Loading @@ -1918,7 +1861,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); if (mCurrentOperatingMode != NORMAL && mCurrentOperatingMode != REPLAY_DATA_INJECTION && !isWhiteListedPackage(connection->getPackageName())) { !isAllowListedPackage(connection->getPackageName())) { return INVALID_OPERATION; } Loading Loading @@ -2266,6 +2209,95 @@ void SensorService::resetTargetSdkVersionCache(const String16& opPackageName) { } } bool SensorService::getTargetOperatingMode(const std::string &inputString, Mode *targetModeOut) { if (inputString == std::string("restrict")) { *targetModeOut = RESTRICTED; return true; } if (inputString == std::string("enable")) { *targetModeOut = NORMAL; return true; } if (inputString == std::string("data_injection")) { *targetModeOut = DATA_INJECTION; return true; } if (inputString == std::string("replay_data_injection")) { *targetModeOut = REPLAY_DATA_INJECTION; return true; } return false; } status_t SensorService::changeOperatingMode(const Vector<String16>& args, Mode targetOperatingMode) { ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); SensorDevice& dev(SensorDevice::getInstance()); if (mCurrentOperatingMode == targetOperatingMode) { return NO_ERROR; } if (targetOperatingMode != NORMAL && args.size() < 2) { return INVALID_OPERATION; } switch (targetOperatingMode) { case NORMAL: // If currently in restricted mode, reset back to NORMAL mode else ignore. if (mCurrentOperatingMode == RESTRICTED) { mCurrentOperatingMode = NORMAL; // enable sensors and recover all sensor direct report enableAllSensorsLocked(&connLock); } if (mCurrentOperatingMode == REPLAY_DATA_INJECTION) { dev.disableAllSensors(); } if (mCurrentOperatingMode == DATA_INJECTION || mCurrentOperatingMode == REPLAY_DATA_INJECTION) { resetToNormalModeLocked(); } mAllowListedPackage.clear(); return status_t(NO_ERROR); case RESTRICTED: // If in any mode other than normal, ignore. if (mCurrentOperatingMode != NORMAL) { return INVALID_OPERATION; } mCurrentOperatingMode = RESTRICTED; // temporarily stop all sensor direct report and disable sensors disableAllSensorsLocked(&connLock); mAllowListedPackage.setTo(String8(args[1])); return status_t(NO_ERROR); case REPLAY_DATA_INJECTION: if (SensorServiceUtil::isUserBuild()) { return INVALID_OPERATION; } FALLTHROUGH_INTENDED; case DATA_INJECTION: if (mCurrentOperatingMode == NORMAL) { dev.disableAllSensors(); // Always use DATA_INJECTION here since this value goes to the HAL and the HAL // doesn't have an understanding of replay vs. normal data injection. status_t err = dev.setMode(DATA_INJECTION); if (err == NO_ERROR) { mCurrentOperatingMode = targetOperatingMode; } if (err != NO_ERROR || targetOperatingMode == REPLAY_DATA_INJECTION) { // Re-enable sensors. dev.enableAllSensors(); } mAllowListedPackage.setTo(String8(args[1])); return NO_ERROR; } else { // Transition to data injection mode supported only from NORMAL mode. return INVALID_OPERATION; } break; default: break; } return NO_ERROR; } void SensorService::checkWakeLockState() { ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); checkWakeLockStateLocked(&connLock); Loading Loading @@ -2295,14 +2327,14 @@ void SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connect } } bool SensorService::isWhiteListedPackage(const String8& packageName) { return (packageName.contains(mWhiteListedPackage.string())); bool SensorService::isAllowListedPackage(const String8& packageName) { return (packageName.contains(mAllowListedPackage.string())); } bool SensorService::isOperationRestrictedLocked(const String16& opPackageName) { if (mCurrentOperatingMode == RESTRICTED) { String8 package(opPackageName); return !isWhiteListedPackage(package); return !isAllowListedPackage(package); } return false; } Loading Loading
libs/binder/libbinder_rpc_unstable.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -112,6 +112,13 @@ ARpcServer* ARpcServer_newInitUnixDomain(AIBinder* service, const char* name) { LOG(ERROR) << "Failed to get fd for the socket:" << name; return nullptr; } // Control socket fds are inherited from init, so they don't have O_CLOEXEC set. // But we don't want any child processes to inherit the socket we are running // the server on, so attempt to set the flag now. if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { LOG(WARNING) << "Failed to set CLOEXEC on control socket with name " << name << " error: " << errno; } if (status_t status = server->setupRawSocketServer(std::move(fd)); status != OK) { LOG(ERROR) << "Failed to set up Unix Domain RPC server with name " << name << " error: " << statusToString(status).c_str(); Loading
services/inputflinger/reader/mapper/gestures/GestureConverter.cpp +8 −4 Original line number Diff line number Diff line Loading @@ -216,12 +216,16 @@ std::list<NotifyArgs> GestureConverter::handleButtonsChange(nsecs_t when, nsecs_ yCursorPosition)); } } // TODO(b/251196347): Set the gesture properties appropriately to avoid needing to negate the Y // values. float rotatedDeltaX = dx, rotatedDeltaY = -dy; rotateDelta(mOrientation, &rotatedDeltaX, &rotatedDeltaY); for (size_t i = 0; i < mSwipeFingerCount; i++) { PointerCoords& coords = mFakeFingerCoords[i]; coords.setAxisValue(AMOTION_EVENT_AXIS_X, coords.getAxisValue(AMOTION_EVENT_AXIS_X) + dx); // TODO(b/251196347): Set the gesture properties appropriately to avoid needing to negate // the Y values. coords.setAxisValue(AMOTION_EVENT_AXIS_Y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y) - dy); coords.setAxisValue(AMOTION_EVENT_AXIS_X, coords.getAxisValue(AMOTION_EVENT_AXIS_X) + rotatedDeltaX); coords.setAxisValue(AMOTION_EVENT_AXIS_Y, coords.getAxisValue(AMOTION_EVENT_AXIS_Y) + rotatedDeltaY); } float xOffset = dx / (mXAxisInfo.maxValue - mXAxisInfo.minValue); // TODO(b/251196347): Set the gesture properties appropriately to avoid needing to negate the Y Loading
services/inputflinger/tests/GestureConverter_test.cpp +77 −0 Original line number Diff line number Diff line Loading @@ -353,6 +353,83 @@ TEST_F(GestureConverterTest, ThreeFingerSwipe_Vertical) { WithPointerCount(1u), WithToolType(AMOTION_EVENT_TOOL_TYPE_FINGER))); } TEST_F(GestureConverterTest, ThreeFingerSwipe_Rotated) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); converter.setOrientation(ui::ROTATION_90); Gesture startGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0, /* dy= */ 10); std::list<NotifyArgs> args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, startGesture); ASSERT_EQ(4u, args.size()); // Three fake fingers should be created. We don't actually care where they are, so long as they // move appropriately. NotifyMotionArgs arg = std::get<NotifyMotionArgs>(args.front()); ASSERT_THAT(arg, AllOf(WithMotionAction(AMOTION_EVENT_ACTION_DOWN), WithGestureOffset(0, 0, EPSILON), WithPointerCount(1u))); PointerCoords finger0Start = arg.pointerCoords[0]; args.pop_front(); arg = std::get<NotifyMotionArgs>(args.front()); ASSERT_THAT(arg, AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u))); PointerCoords finger1Start = arg.pointerCoords[1]; args.pop_front(); arg = std::get<NotifyMotionArgs>(args.front()); ASSERT_THAT(arg, AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_DOWN | 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u))); PointerCoords finger2Start = arg.pointerCoords[2]; args.pop_front(); arg = std::get<NotifyMotionArgs>(args.front()); ASSERT_THAT(arg, AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithGestureOffset(0, -0.01, EPSILON), WithPointerCount(3u))); EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() - 10); EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() - 10); EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() - 10); EXPECT_EQ(arg.pointerCoords[0].getY(), finger0Start.getY()); EXPECT_EQ(arg.pointerCoords[1].getY(), finger1Start.getY()); EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY()); Gesture continueGesture(kGestureSwipe, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME, /* dx= */ 0, /* dy= */ 5); args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, continueGesture); ASSERT_EQ(1u, args.size()); arg = std::get<NotifyMotionArgs>(args.front()); ASSERT_THAT(arg, AllOf(WithMotionAction(AMOTION_EVENT_ACTION_MOVE), WithGestureOffset(0, -0.005, EPSILON), WithPointerCount(3u))); EXPECT_EQ(arg.pointerCoords[0].getX(), finger0Start.getX() - 15); EXPECT_EQ(arg.pointerCoords[1].getX(), finger1Start.getX() - 15); EXPECT_EQ(arg.pointerCoords[2].getX(), finger2Start.getX() - 15); EXPECT_EQ(arg.pointerCoords[0].getY(), finger0Start.getY()); EXPECT_EQ(arg.pointerCoords[1].getY(), finger1Start.getY()); EXPECT_EQ(arg.pointerCoords[2].getY(), finger2Start.getY()); Gesture liftGesture(kGestureSwipeLift, ARBITRARY_GESTURE_TIME, ARBITRARY_GESTURE_TIME); args = converter.handleGesture(ARBITRARY_TIME, READ_TIME, liftGesture); ASSERT_EQ(3u, args.size()); ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP | 2 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithPointerCount(3u))); args.pop_front(); ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_POINTER_UP | 1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT), WithGestureOffset(0, 0, EPSILON), WithPointerCount(2u))); args.pop_front(); ASSERT_THAT(std::get<NotifyMotionArgs>(args.front()), AllOf(WithMotionAction(AMOTION_EVENT_ACTION_UP), WithGestureOffset(0, 0, EPSILON), WithPointerCount(1u))); } TEST_F(GestureConverterTest, FourFingerSwipe_Horizontal) { InputDeviceContext deviceContext(*mDevice, EVENTHUB_ID); GestureConverter converter(*mReader->getContext(), deviceContext, DEVICE_ID); Loading
services/sensorservice/SensorEventConnection.cpp +3 −3 Original line number Diff line number Diff line Loading @@ -82,7 +82,7 @@ void SensorService::SensorEventConnection::resetWakeLockRefCount() { void SensorService::SensorEventConnection::dump(String8& result) { Mutex::Autolock _l(mConnectionLock); result.appendFormat("\tOperating Mode: "); if (!mService->isWhiteListedPackage(getPackageName())) { if (!mService->isAllowListedPackage(getPackageName())) { result.append("RESTRICTED\n"); } else if (mDataInjectionMode) { result.append("DATA_INJECTION\n"); Loading Loading @@ -124,7 +124,7 @@ void SensorService::SensorEventConnection::dump(util::ProtoOutputStream* proto) using namespace service::SensorEventConnectionProto; Mutex::Autolock _l(mConnectionLock); if (!mService->isWhiteListedPackage(getPackageName())) { if (!mService->isAllowListedPackage(getPackageName())) { proto->write(OPERATING_MODE, OP_MODE_RESTRICTED); } else if (mDataInjectionMode) { proto->write(OPERATING_MODE, OP_MODE_DATA_INJECTION); Loading Loading @@ -850,7 +850,7 @@ int SensorService::SensorEventConnection::handleEvent(int fd, int events, void* // Unregister call backs. return 0; } if (!mService->isWhiteListedPackage(mPackageName)) { if (!mService->isAllowListedPackage(mPackageName)) { ALOGE("App not allowed to inject data, dropping event" "package=%s uid=%d", mPackageName.string(), mUid); return 0; Loading
services/sensorservice/SensorService.cpp +114 −82 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ #include <ctime> #include <future> #include <string> #include <private/android_filesystem_config.h> Loading Loading @@ -548,80 +549,22 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { if (args.size() > 2) { return INVALID_OPERATION; } ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); SensorDevice& dev(SensorDevice::getInstance()); if (args.size() == 2 && args[0] == String16("restrict")) { // If already in restricted mode. Ignore. if (mCurrentOperatingMode == RESTRICTED) { return status_t(NO_ERROR); } // If in any mode other than normal, ignore. if (mCurrentOperatingMode != NORMAL) { return INVALID_OPERATION; } mCurrentOperatingMode = RESTRICTED; // temporarily stop all sensor direct report and disable sensors disableAllSensorsLocked(&connLock); mWhiteListedPackage.setTo(String8(args[1])); return status_t(NO_ERROR); } else if (args.size() == 1 && args[0] == String16("enable")) { // If currently in restricted mode, reset back to NORMAL mode else ignore. if (mCurrentOperatingMode == RESTRICTED) { mCurrentOperatingMode = NORMAL; // enable sensors and recover all sensor direct report enableAllSensorsLocked(&connLock); } if (mCurrentOperatingMode == REPLAY_DATA_INJECTION) { dev.disableAllSensors(); } if (mCurrentOperatingMode == DATA_INJECTION || mCurrentOperatingMode == REPLAY_DATA_INJECTION) { resetToNormalModeLocked(); } mWhiteListedPackage.clear(); return status_t(NO_ERROR); } else if (args.size() == 2 && args[0] == String16("data_injection")) { if (mCurrentOperatingMode == NORMAL) { dev.disableAllSensors(); status_t err = dev.setMode(DATA_INJECTION); if (err == NO_ERROR) { mCurrentOperatingMode = DATA_INJECTION; } else { // Re-enable sensors. dev.enableAllSensors(); if (args.size() > 0) { Mode targetOperatingMode = NORMAL; std::string inputStringMode = String8(args[0]).string(); if (getTargetOperatingMode(inputStringMode, &targetOperatingMode)) { status_t error = changeOperatingMode(args, targetOperatingMode); // Dump the latest state only if no error was encountered. if (error != NO_ERROR) { return error; } mWhiteListedPackage.setTo(String8(args[1])); return NO_ERROR; } else if (mCurrentOperatingMode == DATA_INJECTION) { // Already in DATA_INJECTION mode. Treat this as a no_op. return NO_ERROR; } else { // Transition to data injection mode supported only from NORMAL mode. return INVALID_OPERATION; } } else if (args.size() == 2 && args[0] == String16("replay_data_injection") && !SensorServiceUtil::isUserBuild()) { if (mCurrentOperatingMode == NORMAL) { dev.disableAllSensors(); // Use DATA_INJECTION here since this value goes to the HAL and the HAL doesn't // have an understanding of replay vs. normal data injection. status_t err = dev.setMode(DATA_INJECTION); if (err == NO_ERROR) { mCurrentOperatingMode = REPLAY_DATA_INJECTION; } // Re-enable sensors. dev.enableAllSensors(); mWhiteListedPackage.setTo(String8(args[1])); return NO_ERROR; } else if (mCurrentOperatingMode == REPLAY_DATA_INJECTION) { // Already in REPLAY_DATA_INJECTION mode. Treat this as a no_op. return NO_ERROR; } else { // Transition to data injection mode supported only from NORMAL mode. return INVALID_OPERATION; } } else if (args.size() == 1 && args[0] == String16("--proto")) { ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); // Run the following logic if a transition isn't requested above based on the input // argument parsing. if (args.size() == 1 && args[0] == String16("--proto")) { return dumpProtoLocked(fd, &connLock); } else if (!mSensors.hasAnySensor()) { result.append("No Sensors on the device\n"); Loading Loading @@ -680,14 +623,14 @@ status_t SensorService::dump(int fd, const Vector<String16>& args) { result.appendFormat(" NORMAL\n"); break; case RESTRICTED: result.appendFormat(" RESTRICTED : %s\n", mWhiteListedPackage.string()); result.appendFormat(" RESTRICTED : %s\n", mAllowListedPackage.string()); break; case DATA_INJECTION: result.appendFormat(" DATA_INJECTION : %s\n", mWhiteListedPackage.string()); result.appendFormat(" DATA_INJECTION : %s\n", mAllowListedPackage.string()); break; case REPLAY_DATA_INJECTION: result.appendFormat(" REPLAY_DATA_INJECTION : %s\n", mWhiteListedPackage.string()); mAllowListedPackage.string()); break; default: result.appendFormat(" UNKNOWN\n"); Loading Loading @@ -809,11 +752,11 @@ status_t SensorService::dumpProtoLocked(int fd, ConnectionSafeAutolock* connLock break; case RESTRICTED: proto.write(OPERATING_MODE, OP_MODE_RESTRICTED); proto.write(WHITELISTED_PACKAGE, std::string(mWhiteListedPackage.string())); proto.write(WHITELISTED_PACKAGE, std::string(mAllowListedPackage.string())); break; case DATA_INJECTION: proto.write(OPERATING_MODE, OP_MODE_DATA_INJECTION); proto.write(WHITELISTED_PACKAGE, std::string(mWhiteListedPackage.string())); proto.write(WHITELISTED_PACKAGE, std::string(mAllowListedPackage.string())); break; default: proto.write(OPERATING_MODE, OP_MODE_UNKNOWN); Loading Loading @@ -1545,7 +1488,7 @@ sp<ISensorEventConnection> SensorService::createSensorEventConnection(const Stri // operating in DI mode. if (requestedMode == DATA_INJECTION) { if (mCurrentOperatingMode != DATA_INJECTION) return nullptr; if (!isWhiteListedPackage(packageName)) return nullptr; if (!isAllowListedPackage(packageName)) return nullptr; } uid_t uid = IPCThreadState::self()->getCallingUid(); Loading Loading @@ -1918,7 +1861,7 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); if (mCurrentOperatingMode != NORMAL && mCurrentOperatingMode != REPLAY_DATA_INJECTION && !isWhiteListedPackage(connection->getPackageName())) { !isAllowListedPackage(connection->getPackageName())) { return INVALID_OPERATION; } Loading Loading @@ -2266,6 +2209,95 @@ void SensorService::resetTargetSdkVersionCache(const String16& opPackageName) { } } bool SensorService::getTargetOperatingMode(const std::string &inputString, Mode *targetModeOut) { if (inputString == std::string("restrict")) { *targetModeOut = RESTRICTED; return true; } if (inputString == std::string("enable")) { *targetModeOut = NORMAL; return true; } if (inputString == std::string("data_injection")) { *targetModeOut = DATA_INJECTION; return true; } if (inputString == std::string("replay_data_injection")) { *targetModeOut = REPLAY_DATA_INJECTION; return true; } return false; } status_t SensorService::changeOperatingMode(const Vector<String16>& args, Mode targetOperatingMode) { ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); SensorDevice& dev(SensorDevice::getInstance()); if (mCurrentOperatingMode == targetOperatingMode) { return NO_ERROR; } if (targetOperatingMode != NORMAL && args.size() < 2) { return INVALID_OPERATION; } switch (targetOperatingMode) { case NORMAL: // If currently in restricted mode, reset back to NORMAL mode else ignore. if (mCurrentOperatingMode == RESTRICTED) { mCurrentOperatingMode = NORMAL; // enable sensors and recover all sensor direct report enableAllSensorsLocked(&connLock); } if (mCurrentOperatingMode == REPLAY_DATA_INJECTION) { dev.disableAllSensors(); } if (mCurrentOperatingMode == DATA_INJECTION || mCurrentOperatingMode == REPLAY_DATA_INJECTION) { resetToNormalModeLocked(); } mAllowListedPackage.clear(); return status_t(NO_ERROR); case RESTRICTED: // If in any mode other than normal, ignore. if (mCurrentOperatingMode != NORMAL) { return INVALID_OPERATION; } mCurrentOperatingMode = RESTRICTED; // temporarily stop all sensor direct report and disable sensors disableAllSensorsLocked(&connLock); mAllowListedPackage.setTo(String8(args[1])); return status_t(NO_ERROR); case REPLAY_DATA_INJECTION: if (SensorServiceUtil::isUserBuild()) { return INVALID_OPERATION; } FALLTHROUGH_INTENDED; case DATA_INJECTION: if (mCurrentOperatingMode == NORMAL) { dev.disableAllSensors(); // Always use DATA_INJECTION here since this value goes to the HAL and the HAL // doesn't have an understanding of replay vs. normal data injection. status_t err = dev.setMode(DATA_INJECTION); if (err == NO_ERROR) { mCurrentOperatingMode = targetOperatingMode; } if (err != NO_ERROR || targetOperatingMode == REPLAY_DATA_INJECTION) { // Re-enable sensors. dev.enableAllSensors(); } mAllowListedPackage.setTo(String8(args[1])); return NO_ERROR; } else { // Transition to data injection mode supported only from NORMAL mode. return INVALID_OPERATION; } break; default: break; } return NO_ERROR; } void SensorService::checkWakeLockState() { ConnectionSafeAutolock connLock = mConnectionHolder.lock(mLock); checkWakeLockStateLocked(&connLock); Loading Loading @@ -2295,14 +2327,14 @@ void SensorService::sendEventsFromCache(const sp<SensorEventConnection>& connect } } bool SensorService::isWhiteListedPackage(const String8& packageName) { return (packageName.contains(mWhiteListedPackage.string())); bool SensorService::isAllowListedPackage(const String8& packageName) { return (packageName.contains(mAllowListedPackage.string())); } bool SensorService::isOperationRestrictedLocked(const String16& opPackageName) { if (mCurrentOperatingMode == RESTRICTED) { String8 package(opPackageName); return !isWhiteListedPackage(package); return !isAllowListedPackage(package); } return false; } Loading