diff options
Diffstat (limited to 'libs')
-rw-r--r-- | libs/binder/Android.mk | 2 | ||||
-rw-r--r-- | libs/binder/IInterface.cpp | 21 | ||||
-rw-r--r-- | libs/binder/IPCThreadState.cpp | 21 | ||||
-rw-r--r-- | libs/binder/IProcessInfoService.cpp | 94 | ||||
-rw-r--r-- | libs/binder/Parcel.cpp | 173 | ||||
-rw-r--r-- | libs/binder/ProcessInfoService.cpp | 70 | ||||
-rw-r--r-- | libs/binder/ProcessState.cpp | 13 | ||||
-rw-r--r-- | libs/gui/ISensorServer.cpp | 25 | ||||
-rw-r--r-- | libs/gui/SensorEventQueue.cpp | 10 | ||||
-rw-r--r-- | libs/gui/SensorManager.cpp | 21 | ||||
-rw-r--r-- | libs/input/Android.mk | 1 | ||||
-rw-r--r-- | libs/input/IInputFlinger.cpp | 59 | ||||
-rw-r--r-- | libs/input/InputDevice.cpp | 13 |
13 files changed, 492 insertions, 31 deletions
diff --git a/libs/binder/Android.mk b/libs/binder/Android.mk index 79decfe..d5860ef 100644 --- a/libs/binder/Android.mk +++ b/libs/binder/Android.mk @@ -26,6 +26,8 @@ sources := \ IMemory.cpp \ IPCThreadState.cpp \ IPermissionController.cpp \ + IProcessInfoService.cpp \ + ProcessInfoService.cpp \ IServiceManager.cpp \ MemoryDealer.cpp \ MemoryBase.cpp \ diff --git a/libs/binder/IInterface.cpp b/libs/binder/IInterface.cpp index 8c60dc4..2fcd3d9 100644 --- a/libs/binder/IInterface.cpp +++ b/libs/binder/IInterface.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "IInterface" +#include <utils/Log.h> #include <binder/IInterface.h> namespace android { @@ -41,6 +43,25 @@ sp<IBinder> IInterface::asBinder(const sp<IInterface>& iface) return iface->onAsBinder(); } + // --------------------------------------------------------------------------- }; // namespace android + +extern "C" { + +void _ZN7android10IInterface8asBinderEv(void *retval, void* self) { + ALOGW("deprecated asBinder call, please update your code"); + //ALOGI("self: %p, retval: %p", self, retval); + android::sp<android::IBinder> *ret = new(retval) android::sp<android::IBinder>; + *ret = android::IInterface::asBinder((android::IInterface*)self); +} + +void _ZNK7android10IInterface8asBinderEv(void *retval, void *self) { + ALOGW("deprecated asBinder call, please update your code"); + //ALOGI("self: %p, retval: %p", self, retval); + android::sp<android::IBinder> *ret = new(retval) android::sp<android::IBinder>; + *ret = android::IInterface::asBinder((android::IInterface*)self); +} + +} // extern "C" diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp index 9f68aa8..ef88181 100644 --- a/libs/binder/IPCThreadState.cpp +++ b/libs/binder/IPCThreadState.cpp @@ -399,6 +399,18 @@ void IPCThreadState::flushCommands() talkWithDriver(false); } +void IPCThreadState::blockUntilThreadAvailable() +{ + pthread_mutex_lock(&mProcess->mThreadCountLock); + while (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads) { + ALOGW("Waiting for thread to be free. mExecutingThreadsCount=%lu mMaxThreads=%lu\n", + static_cast<unsigned long>(mProcess->mExecutingThreadsCount), + static_cast<unsigned long>(mProcess->mMaxThreads)); + pthread_cond_wait(&mProcess->mThreadCountDecrement, &mProcess->mThreadCountLock); + } + pthread_mutex_unlock(&mProcess->mThreadCountLock); +} + status_t IPCThreadState::getAndExecuteCommand() { status_t result; @@ -414,8 +426,17 @@ status_t IPCThreadState::getAndExecuteCommand() << getReturnString(cmd) << endl; } + pthread_mutex_lock(&mProcess->mThreadCountLock); + mProcess->mExecutingThreadsCount++; + pthread_mutex_unlock(&mProcess->mThreadCountLock); + result = executeCommand(cmd); + pthread_mutex_lock(&mProcess->mThreadCountLock); + mProcess->mExecutingThreadsCount--; + pthread_cond_broadcast(&mProcess->mThreadCountDecrement); + pthread_mutex_unlock(&mProcess->mThreadCountLock); + // After executing the command, ensure that the thread is returned to the // foreground cgroup before rejoining the pool. The driver takes care of // restoring the priority, but doesn't do anything with cgroups so we diff --git a/libs/binder/IProcessInfoService.cpp b/libs/binder/IProcessInfoService.cpp new file mode 100644 index 0000000..d86eb27 --- /dev/null +++ b/libs/binder/IProcessInfoService.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <binder/IProcessInfoService.h> +#include <binder/Parcel.h> +#include <utils/Errors.h> +#include <sys/types.h> + +namespace android { + +// ---------------------------------------------------------------------- + +class BpProcessInfoService : public BpInterface<IProcessInfoService> { +public: + BpProcessInfoService(const sp<IBinder>& impl) + : BpInterface<IProcessInfoService>(impl) {} + + virtual status_t getProcessStatesFromPids(size_t length, /*in*/ int32_t* pids, + /*out*/ int32_t* states) + { + Parcel data, reply; + data.writeInterfaceToken(IProcessInfoService::getInterfaceDescriptor()); + data.writeInt32Array(length, pids); + data.writeInt32(length); // write length of output array, used by java AIDL stubs + status_t err = remote()->transact(GET_PROCESS_STATES_FROM_PIDS, data, &reply); + if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) { + return err; + } + int32_t replyLen = reply.readInt32(); + if (static_cast<size_t>(replyLen) != length) { + return NOT_ENOUGH_DATA; + } + if (replyLen > 0 && (err = reply.read(states, length * sizeof(*states))) != NO_ERROR) { + return err; + } + return reply.readInt32(); + } + +}; + +IMPLEMENT_META_INTERFACE(ProcessInfoService, "android.os.IProcessInfoService"); + +// ---------------------------------------------------------------------- + +status_t BnProcessInfoService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, + uint32_t flags) { + switch(code) { + case GET_PROCESS_STATES_FROM_PIDS: { + CHECK_INTERFACE(IProcessInfoService, data, reply); + int32_t arrayLen = data.readInt32(); + if (arrayLen <= 0) { + reply->writeNoException(); + reply->writeInt32(0); + reply->writeInt32(NOT_ENOUGH_DATA); + return NO_ERROR; + } + + size_t len = static_cast<size_t>(arrayLen); + int32_t pids[len]; + status_t res = data.read(pids, len * sizeof(*pids)); + + // Ignore output array length returned in the parcel here, as the states array must + // always be the same length as the input PIDs array. + int32_t states[len]; + for (size_t i = 0; i < len; i++) states[i] = -1; + if (res == NO_ERROR) { + res = getProcessStatesFromPids(len, /*in*/ pids, /*out*/ states); + } + reply->writeNoException(); + reply->writeInt32Array(len, states); + reply->writeInt32(res); + return NO_ERROR; + } break; + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +// ---------------------------------------------------------------------- + +}; // namespace android diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 2c566f9..0e11d53 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -54,7 +54,17 @@ // --------------------------------------------------------------------------- -#define PAD_SIZE(s) (((s)+3)&~3) +// This macro should never be used at runtime, as a too large value +// of s could cause an integer overflow. Instead, you should always +// use the wrapper function pad_size() +#define PAD_SIZE_UNSAFE(s) (((s)+3)&~3) + +static size_t pad_size(size_t s) { + if (s > (SIZE_T_MAX - 3)) { + abort(); + } + return PAD_SIZE_UNSAFE(s); +} // Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER #define STRICT_MODE_PENALTY_GATHER (0x40 << 16) @@ -355,6 +365,12 @@ size_t Parcel::dataCapacity() const status_t Parcel::setDataSize(size_t size) { + if (size > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + status_t err; err = continueWrite(size); if (err == NO_ERROR) { @@ -366,18 +382,36 @@ status_t Parcel::setDataSize(size_t size) void Parcel::setDataPosition(size_t pos) const { + if (pos > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + abort(); + } + mDataPos = pos; mNextObjectHint = 0; } status_t Parcel::setDataCapacity(size_t size) { + if (size > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + if (size > mDataCapacity) return continueWrite(size); return NO_ERROR; } status_t Parcel::setData(const uint8_t* buffer, size_t len) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + status_t err = restartWrite(len); if (err == NO_ERROR) { memcpy(const_cast<uint8_t*>(data()), buffer, len); @@ -401,6 +435,12 @@ status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len) return NO_ERROR; } + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + // range checks against the source parcel size if ((offset > parcel->mDataSize) || (len > parcel->mDataSize) @@ -561,6 +601,12 @@ void Parcel::setError(status_t err) status_t Parcel::finishWrite(size_t len) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + //printf("Finish write of %d\n", len); mDataPos += len; ALOGV("finishWrite Setting data pos of %p to %zu", this, mDataPos); @@ -574,6 +620,12 @@ status_t Parcel::finishWrite(size_t len) status_t Parcel::writeUnpadded(const void* data, size_t len) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + size_t end = mDataPos + len; if (end < mDataPos) { // integer overflow @@ -593,6 +645,12 @@ restart_write: status_t Parcel::write(const void* data, size_t len) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + void* const d = writeInplace(len); if (d) { memcpy(d, data, len); @@ -603,7 +661,13 @@ status_t Parcel::write(const void* data, size_t len) void* Parcel::writeInplace(size_t len) { - const size_t padded = PAD_SIZE(len); + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return NULL; + } + + const size_t padded = pad_size(len); // sanity check for integer overflow if (mDataPos+padded < mDataPos) { @@ -652,6 +716,12 @@ status_t Parcel::writeUint32(uint32_t val) } status_t Parcel::writeInt32Array(size_t len, const int32_t *val) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + if (!val) { return writeAligned(-1); } @@ -662,6 +732,12 @@ status_t Parcel::writeInt32Array(size_t len, const int32_t *val) { return ret; } status_t Parcel::writeByteArray(size_t len, const uint8_t *val) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + if (!val) { return writeAligned(-1); } @@ -677,6 +753,11 @@ status_t Parcel::writeInt64(int64_t val) return writeAligned(val); } +status_t Parcel::writeUint64(uint64_t val) +{ + return writeAligned(val); +} + status_t Parcel::writePointer(uintptr_t val) { return writeAligned<binder_uintptr_t>(val); @@ -835,6 +916,12 @@ status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob) { status_t status; + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + if (!mAllowFds || len <= IN_PLACE_BLOB_LIMIT) { ALOGV("writeBlob: write in place"); status = writeInt32(0); @@ -851,6 +938,8 @@ status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob) int fd = ashmem_create_region("Parcel Blob", len); if (fd < 0) return NO_MEMORY; + mBlobAshmemSize += len; + int result = ashmem_set_prot_region(fd, PROT_READ | PROT_WRITE); if (result < 0) { status = result; @@ -887,6 +976,12 @@ status_t Parcel::write(const FlattenableHelperInterface& val) const size_t len = val.getFlattenedSize(); const size_t fd_count = val.getFdCount(); + if ((len > INT32_MAX) || (fd_count > INT32_MAX)) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + err = this->writeInt32(len); if (err) return err; @@ -894,7 +989,7 @@ status_t Parcel::write(const FlattenableHelperInterface& val) if (err) return err; // payload - void* const buf = this->writeInplace(PAD_SIZE(len)); + void* const buf = this->writeInplace(pad_size(len)); if (buf == NULL) return BAD_VALUE; @@ -968,10 +1063,16 @@ void Parcel::remove(size_t /*start*/, size_t /*amt*/) status_t Parcel::read(void* outData, size_t len) const { - if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize - && len <= PAD_SIZE(len)) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + + if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize + && len <= pad_size(len)) { memcpy(outData, mData+mDataPos, len); - mDataPos += PAD_SIZE(len); + mDataPos += pad_size(len); ALOGV("read Setting data pos of %p to %zu", this, mDataPos); return NO_ERROR; } @@ -980,10 +1081,16 @@ status_t Parcel::read(void* outData, size_t len) const const void* Parcel::readInplace(size_t len) const { - if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize - && len <= PAD_SIZE(len)) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return NULL; + } + + if ((mDataPos+pad_size(len)) >= mDataPos && (mDataPos+pad_size(len)) <= mDataSize + && len <= pad_size(len)) { const void* data = mData+mDataPos; - mDataPos += PAD_SIZE(len); + mDataPos += pad_size(len); ALOGV("readInplace Setting data pos of %p to %zu", this, mDataPos); return data; } @@ -992,7 +1099,7 @@ const void* Parcel::readInplace(size_t len) const template<class T> status_t Parcel::readAligned(T *pArg) const { - COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T)); + COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); if ((mDataPos+sizeof(T)) <= mDataSize) { const void* data = mData+mDataPos; @@ -1016,7 +1123,7 @@ T Parcel::readAligned() const { template<class T> status_t Parcel::writeAligned(T val) { - COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE(sizeof(T)) == sizeof(T)); + COMPILE_TIME_ASSERT_FUNCTION_SCOPE(PAD_SIZE_UNSAFE(sizeof(T)) == sizeof(T)); if ((mDataPos+sizeof(val)) <= mDataCapacity) { restart_write: @@ -1060,6 +1167,16 @@ int64_t Parcel::readInt64() const return readAligned<int64_t>(); } +status_t Parcel::readUint64(uint64_t *pArg) const +{ + return readAligned(pArg); +} + +uint64_t Parcel::readUint64() const +{ + return readAligned<uint64_t>(); +} + status_t Parcel::readPointer(uintptr_t *pArg) const { status_t ret; @@ -1147,7 +1264,7 @@ const char* Parcel::readCString() const const char* eos = reinterpret_cast<const char*>(memchr(str, 0, avail)); if (eos) { const size_t len = eos - str; - mDataPos += PAD_SIZE(len+1); + mDataPos += pad_size(len+1); ALOGV("readCString Setting data pos of %p to %zu", this, mDataPos); return str; } @@ -1306,8 +1423,14 @@ status_t Parcel::read(FlattenableHelperInterface& val) const const size_t len = this->readInt32(); const size_t fd_count = this->readInt32(); + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + // payload - void const* const buf = this->readInplace(PAD_SIZE(len)); + void const* const buf = this->readInplace(pad_size(len)); if (buf == NULL) return BAD_VALUE; @@ -1546,6 +1669,12 @@ void Parcel::freeDataNoInit() status_t Parcel::growData(size_t len) { + if (len > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + size_t newSize = ((mDataSize+len)*3)/2; return (newSize <= mDataSize) ? (status_t) NO_MEMORY @@ -1554,6 +1683,12 @@ status_t Parcel::growData(size_t len) status_t Parcel::restartWrite(size_t desired) { + if (desired > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + if (mOwner) { freeData(); return continueWrite(desired); @@ -1594,6 +1729,12 @@ status_t Parcel::restartWrite(size_t desired) status_t Parcel::continueWrite(size_t desired) { + if (desired > INT32_MAX) { + // don't accept size_t values which may have come from an + // inadvertent conversion from a negative int. + return BAD_VALUE; + } + // If shrinking, first adjust for any objects that appear // after the new data size. size_t objectsSize = mObjectsSize; @@ -1762,6 +1903,7 @@ void Parcel::initState() mFdsKnown = true; mAllowFds = true; mOwner = NULL; + mBlobAshmemSize = 0; } void Parcel::scanForFds() const @@ -1779,6 +1921,11 @@ void Parcel::scanForFds() const mFdsKnown = true; } +size_t Parcel::getBlobAshmemSize() const +{ + return mBlobAshmemSize; +} + // --- Parcel::Blob --- Parcel::Blob::Blob() : diff --git a/libs/binder/ProcessInfoService.cpp b/libs/binder/ProcessInfoService.cpp new file mode 100644 index 0000000..fb28643 --- /dev/null +++ b/libs/binder/ProcessInfoService.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <binder/ProcessInfoService.h> +#include <binder/IServiceManager.h> + +#include <utils/Log.h> +#include <utils/String16.h> + +namespace android { + +ProcessInfoService::ProcessInfoService() { + updateBinderLocked(); +} + +status_t ProcessInfoService::getProcessStatesImpl(size_t length, /*in*/ int32_t* pids, + /*out*/ int32_t* states) { + status_t err = NO_ERROR; + sp<IProcessInfoService> pis; + mProcessInfoLock.lock(); + pis = mProcessInfoService; + mProcessInfoLock.unlock(); + + for (int i = 0; i < BINDER_ATTEMPT_LIMIT; i++) { + + if (pis != NULL) { + err = pis->getProcessStatesFromPids(length, /*in*/ pids, /*out*/ states); + if (err == NO_ERROR) return NO_ERROR; // success + if (IInterface::asBinder(pis)->isBinderAlive()) return err; + } + sleep(1); + + mProcessInfoLock.lock(); + if (pis == mProcessInfoService) { + updateBinderLocked(); + } + pis = mProcessInfoService; + mProcessInfoLock.unlock(); + } + + ALOGW("%s: Could not retrieve process states from ProcessInfoService after %d retries.", + __FUNCTION__, BINDER_ATTEMPT_LIMIT); + + return TIMED_OUT; +} + +void ProcessInfoService::updateBinderLocked() { + const sp<IServiceManager> sm(defaultServiceManager()); + if (sm != NULL) { + const String16 name("processinfo"); + mProcessInfoService = interface_cast<IProcessInfoService>(sm->checkService(name)); + } +} + +ANDROID_SINGLETON_STATIC_INSTANCE(ProcessInfoService); + +}; // namespace android diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp index 303d6cf..016d3c5 100644 --- a/libs/binder/ProcessState.cpp +++ b/libs/binder/ProcessState.cpp @@ -42,12 +42,13 @@ #include <sys/stat.h> #define BINDER_VM_SIZE ((1*1024*1024) - (4096 *2)) +#define DEFAULT_MAX_BINDER_THREADS 15 // --------------------------------------------------------------------------- namespace android { - + class PoolThread : public Thread { public: @@ -294,7 +295,9 @@ void ProcessState::spawnPooledThread(bool isMain) status_t ProcessState::setThreadPoolMaxThreadCount(size_t maxThreads) { status_t result = NO_ERROR; - if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &maxThreads) == -1) { + if (ioctl(mDriverFD, BINDER_SET_MAX_THREADS, &maxThreads) != -1) { + mMaxThreads = maxThreads; + } else { result = -errno; ALOGE("Binder ioctl to set max threads failed: %s", strerror(-result)); } @@ -322,7 +325,7 @@ static int open_driver() close(fd); fd = -1; } - size_t maxThreads = 15; + size_t maxThreads = DEFAULT_MAX_BINDER_THREADS; result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads); if (result == -1) { ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno)); @@ -336,6 +339,10 @@ static int open_driver() ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED) + , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER) + , mThreadCountDecrement(PTHREAD_COND_INITIALIZER) + , mExecutingThreadsCount(0) + , mMaxThreads(DEFAULT_MAX_BINDER_THREADS) , mManagesContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp index 8e09e7c..140712e 100644 --- a/libs/gui/ISensorServer.cpp +++ b/libs/gui/ISensorServer.cpp @@ -35,6 +35,7 @@ namespace android { enum { GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION, CREATE_SENSOR_EVENT_CONNECTION, + ENABLE_DATA_INJECTION }; class BpSensorServer : public BpInterface<ISensorServer> @@ -63,13 +64,24 @@ public: return v; } - virtual sp<ISensorEventConnection> createSensorEventConnection() + virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName, + int mode) { Parcel data, reply; data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor()); + data.writeString8(packageName); + data.writeInt32(mode); remote()->transact(CREATE_SENSOR_EVENT_CONNECTION, data, &reply); return interface_cast<ISensorEventConnection>(reply.readStrongBinder()); } + + virtual status_t enableDataInjection(int enable) { + Parcel data, reply; + data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor()); + data.writeInt32(enable); + remote()->transact(ENABLE_DATA_INJECTION, data, &reply); + return reply.readInt32(); + } }; // Out-of-line virtual method definition to trigger vtable emission in this @@ -96,10 +108,19 @@ status_t BnSensorServer::onTransact( } case CREATE_SENSOR_EVENT_CONNECTION: { CHECK_INTERFACE(ISensorServer, data, reply); - sp<ISensorEventConnection> connection(createSensorEventConnection()); + String8 packageName = data.readString8(); + int32_t mode = data.readInt32(); + sp<ISensorEventConnection> connection(createSensorEventConnection(packageName, mode)); reply->writeStrongBinder(IInterface::asBinder(connection)); return NO_ERROR; } + case ENABLE_DATA_INJECTION: { + CHECK_INTERFACE(ISensorServer, data, reply); + int32_t enable = data.readInt32(); + status_t ret = enableDataInjection(enable); + reply->writeInt32(static_cast<int32_t>(ret)); + return NO_ERROR; + } } return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp index 76ae470..8b2018f 100644 --- a/libs/gui/SensorEventQueue.cpp +++ b/libs/gui/SensorEventQueue.cpp @@ -149,6 +149,16 @@ status_t SensorEventQueue::setEventRate(Sensor const* sensor, nsecs_t ns) const return mSensorEventConnection->setEventRate(sensor->getHandle(), ns); } +status_t SensorEventQueue::injectSensorEvent(const ASensorEvent& event) { + // Blocking call. + ssize_t size = ::send(mSensorChannel->getFd(), &event, sizeof(event), MSG_NOSIGNAL); + if (size < 0) { + ALOGE("injectSensorEvent failure %zd %d", size, mSensorChannel->getFd()); + return INVALID_OPERATION; + } + return NO_ERROR; +} + void SensorEventQueue::sendAck(const ASensorEvent* events, int count) { for (int i = 0; i < count; ++i) { if (events[i].flags & WAKE_UP_SENSOR_EVENT_NEEDS_ACK) { diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp index d6df404..cedcf56 100644 --- a/libs/gui/SensorManager.cpp +++ b/libs/gui/SensorManager.cpp @@ -100,8 +100,6 @@ status_t SensorManager::assertStateLocked() const { return NO_ERROR; } - - ssize_t SensorManager::getSensorList(Sensor const* const** list) const { Mutex::Autolock _l(mLock); @@ -139,18 +137,17 @@ Sensor const* SensorManager::getDefaultSensor(int type) return NULL; } -sp<SensorEventQueue> SensorManager::createEventQueue() -{ +sp<SensorEventQueue> SensorManager::createEventQueue(String8 packageName, int mode) { sp<SensorEventQueue> queue; Mutex::Autolock _l(mLock); while (assertStateLocked() == NO_ERROR) { sp<ISensorEventConnection> connection = - mSensorServer->createSensorEventConnection(); + mSensorServer->createSensorEventConnection(packageName, mode); if (connection == NULL) { - // SensorService just died. - ALOGE("createEventQueue: connection is NULL. SensorService died."); - continue; + // SensorService just died or the app doesn't have required permissions. + ALOGE("createEventQueue: connection is NULL."); + return NULL; } queue = new SensorEventQueue(connection); break; @@ -158,5 +155,13 @@ sp<SensorEventQueue> SensorManager::createEventQueue() return queue; } +status_t SensorManager::enableDataInjection(bool enable) { + Mutex::Autolock _l(mLock); + if (assertStateLocked() == NO_ERROR) { + return mSensorServer->enableDataInjection(enable); + } + return INVALID_OPERATION; +} + // ---------------------------------------------------------------------------- }; // namespace android diff --git a/libs/input/Android.mk b/libs/input/Android.mk index f1921a4..944ac7f 100644 --- a/libs/input/Android.mk +++ b/libs/input/Android.mk @@ -27,6 +27,7 @@ commonSources := \ deviceSources := \ $(commonSources) \ + IInputFlinger.cpp \ InputTransport.cpp \ VelocityControl.cpp \ VelocityTracker.cpp diff --git a/libs/input/IInputFlinger.cpp b/libs/input/IInputFlinger.cpp new file mode 100644 index 0000000..e009731 --- /dev/null +++ b/libs/input/IInputFlinger.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdint.h> +#include <sys/types.h> + +#include <binder/Parcel.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> + +#include <input/IInputFlinger.h> + + +namespace android { + +class BpInputFlinger : public BpInterface<IInputFlinger> { +public: + BpInputFlinger(const sp<IBinder>& impl) : + BpInterface<IInputFlinger>(impl) { } + + virtual status_t doSomething() { + Parcel data, reply; + data.writeInterfaceToken(IInputFlinger::getInterfaceDescriptor()); + remote()->transact(BnInputFlinger::DO_SOMETHING_TRANSACTION, data, &reply); + return reply.readInt32(); + } +}; + +IMPLEMENT_META_INTERFACE(InputFlinger, "android.input.IInputFlinger"); + + +status_t BnInputFlinger::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { + switch(code) { + case DO_SOMETHING_TRANSACTION: { + CHECK_INTERFACE(IInputFlinger, data, reply); + reply->writeInt32(0); + break; + } + default: + return BBinder::onTransact(code, data, reply, flags); + } + return NO_ERROR; +} + +}; diff --git a/libs/input/InputDevice.cpp b/libs/input/InputDevice.cpp index b11110a..d755ed3 100644 --- a/libs/input/InputDevice.cpp +++ b/libs/input/InputDevice.cpp @@ -127,28 +127,31 @@ String8 getInputDeviceConfigurationFilePathByName( // --- InputDeviceInfo --- InputDeviceInfo::InputDeviceInfo() { - initialize(-1, 0, -1, InputDeviceIdentifier(), String8(), false); + initialize(-1, 0, -1, InputDeviceIdentifier(), String8(), false, false); } InputDeviceInfo::InputDeviceInfo(const InputDeviceInfo& other) : mId(other.mId), mGeneration(other.mGeneration), mControllerNumber(other.mControllerNumber), mIdentifier(other.mIdentifier), mAlias(other.mAlias), mIsExternal(other.mIsExternal), - mSources(other.mSources), mKeyboardType(other.mKeyboardType), - mKeyCharacterMap(other.mKeyCharacterMap), mHasVibrator(other.mHasVibrator), - mHasButtonUnderPad(other.mHasButtonUnderPad), mMotionRanges(other.mMotionRanges) { + mHasMic(other.mHasMic), mSources(other.mSources), + mKeyboardType(other.mKeyboardType), mKeyCharacterMap(other.mKeyCharacterMap), + mHasVibrator(other.mHasVibrator), mHasButtonUnderPad(other.mHasButtonUnderPad), + mMotionRanges(other.mMotionRanges) { } InputDeviceInfo::~InputDeviceInfo() { } void InputDeviceInfo::initialize(int32_t id, int32_t generation, int32_t controllerNumber, - const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal) { + const InputDeviceIdentifier& identifier, const String8& alias, bool isExternal, + bool hasMic) { mId = id; mGeneration = generation; mControllerNumber = controllerNumber; mIdentifier = identifier; mAlias = alias; mIsExternal = isExternal; + mHasMic = hasMic; mSources = 0; mKeyboardType = AINPUT_KEYBOARD_TYPE_NONE; mHasVibrator = false; |