diff options
Diffstat (limited to 'services')
-rw-r--r-- | services/input/EventHub.cpp | 67 | ||||
-rw-r--r-- | services/input/EventHub.h | 4 | ||||
-rw-r--r-- | services/input/InputReader.cpp | 25 | ||||
-rw-r--r-- | services/input/InputReader.h | 9 | ||||
-rw-r--r-- | services/input/tests/InputReader_test.cpp | 29 | ||||
-rw-r--r-- | services/java/com/android/server/AlarmManagerService.java | 36 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 11 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityRecord.java | 3 | ||||
-rw-r--r-- | services/jni/com_android_server_input_InputManagerService.cpp | 14 |
9 files changed, 149 insertions, 49 deletions
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp index 1b74aa6..665d711 100644 --- a/services/input/EventHub.cpp +++ b/services/input/EventHub.cpp @@ -40,6 +40,7 @@ #include <androidfw/KeyCharacterMap.h> #include <androidfw/VirtualKeyMap.h> +#include <sha1.h> #include <string.h> #include <stdint.h> #include <dirent.h> @@ -78,6 +79,20 @@ static inline const char* toString(bool value) { return value ? "true" : "false"; } +static String8 sha1(const String8& in) { + SHA1_CTX ctx; + SHA1Init(&ctx); + SHA1Update(&ctx, reinterpret_cast<const u_char*>(in.string()), in.size()); + u_char digest[SHA1_DIGEST_LENGTH]; + SHA1Final(digest, &ctx); + + String8 out; + for (size_t i = 0; i < SHA1_DIGEST_LENGTH; i++) { + out.appendFormat("%02x", digest[i]); + } + return out; +} + // --- Global Functions --- uint32_t getAbsAxisUsage(int32_t axis, uint32_t deviceClasses) { @@ -209,11 +224,11 @@ EventHub::~EventHub(void) { release_wake_lock(WAKE_LOCK_ID); } -String8 EventHub::getDeviceName(int32_t deviceId) const { +InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); - if (device == NULL) return String8(); - return device->identifier.name; + if (device == NULL) return InputDeviceIdentifier(); + return device->identifier; } uint32_t EventHub::getDeviceClasses(int32_t deviceId) const { @@ -893,6 +908,30 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { identifier.uniqueId.setTo(buffer); } + // Compute a device descriptor that uniquely identifies the device. + // The descriptor is assumed to be a stable identifier. Its value should not + // change between reboots, reconnections, firmware updates or new releases of Android. + // Ideally, we also want the descriptor to be short and relatively opaque. + String8 rawDescriptor; + rawDescriptor.appendFormat(":%04x:%04x:", identifier.vendor, identifier.product); + if (!identifier.uniqueId.isEmpty()) { + rawDescriptor.append("uniqueId:"); + rawDescriptor.append(identifier.uniqueId); + } if (identifier.vendor == 0 && identifier.product == 0) { + // If we don't know the vendor and product id, then the device is probably + // built-in so we need to rely on other information to uniquely identify + // the input device. Usually we try to avoid relying on the device name or + // location but for built-in input device, they are unlikely to ever change. + if (!identifier.name.isEmpty()) { + rawDescriptor.append("name:"); + rawDescriptor.append(identifier.name); + } else if (!identifier.location.isEmpty()) { + rawDescriptor.append("location:"); + rawDescriptor.append(identifier.location); + } + } + identifier.descriptor = sha1(rawDescriptor); + // Make file descriptor non-blocking for use with poll(). if (fcntl(fd, F_SETFL, O_NONBLOCK)) { ALOGE("Error %d making device file descriptor non-blocking.", errno); @@ -904,19 +943,18 @@ status_t EventHub::openDeviceLocked(const char *devicePath) { int32_t deviceId = mNextDeviceId++; Device* device = new Device(fd, deviceId, String8(devicePath), identifier); -#if 0 - ALOGI("add device %d: %s\n", deviceId, devicePath); - ALOGI(" bus: %04x\n" - " vendor %04x\n" - " product %04x\n" - " version %04x\n", + ALOGV("add device %d: %s\n", deviceId, devicePath); + ALOGV(" bus: %04x\n" + " vendor %04x\n" + " product %04x\n" + " version %04x\n", identifier.bus, identifier.vendor, identifier.product, identifier.version); - ALOGI(" name: \"%s\"\n", identifier.name.string()); - ALOGI(" location: \"%s\"\n", identifier.location.string()); - ALOGI(" unique id: \"%s\"\n", identifier.uniqueId.string()); - ALOGI(" driver: v%d.%d.%d\n", + ALOGV(" name: \"%s\"\n", identifier.name.string()); + ALOGV(" location: \"%s\"\n", identifier.location.string()); + ALOGV(" unique id: \"%s\"\n", identifier.uniqueId.string()); + ALOGV(" descriptor: \"%s\" (%s)\n", identifier.descriptor.string(), rawDescriptor.string()); + ALOGV(" driver: v%d.%d.%d\n", driverVersion >> 16, (driverVersion >> 8) & 0xff, driverVersion & 0xff); -#endif // Load the configuration file for the device. loadConfigurationLocked(device); @@ -1303,6 +1341,7 @@ void EventHub::dump(String8& dump) { } dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes); dump.appendFormat(INDENT3 "Path: %s\n", device->path.string()); + dump.appendFormat(INDENT3 "Descriptor: %s\n", device->identifier.descriptor.string()); dump.appendFormat(INDENT3 "Location: %s\n", device->identifier.location.string()); dump.appendFormat(INDENT3 "UniqueId: %s\n", device->identifier.uniqueId.string()); dump.appendFormat(INDENT3 "Identifier: bus=0x%04x, vendor=0x%04x, " diff --git a/services/input/EventHub.h b/services/input/EventHub.h index 4eb47c6..bd21a3d 100644 --- a/services/input/EventHub.h +++ b/services/input/EventHub.h @@ -151,7 +151,7 @@ public: virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0; - virtual String8 getDeviceName(int32_t deviceId) const = 0; + virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const = 0; virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const = 0; @@ -230,7 +230,7 @@ public: virtual uint32_t getDeviceClasses(int32_t deviceId) const; - virtual String8 getDeviceName(int32_t deviceId) const; + virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const; virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const; diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp index eccce29..ddd870d 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -344,18 +344,19 @@ void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) { } void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) { - String8 name = mEventHub->getDeviceName(deviceId); + InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId); uint32_t classes = mEventHub->getDeviceClasses(deviceId); - InputDevice* device = createDeviceLocked(deviceId, name, classes); + InputDevice* device = createDeviceLocked(deviceId, identifier, classes); device->configure(when, &mConfig, 0); device->reset(when); if (device->isIgnored()) { - ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId, name.string()); + ALOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId, + identifier.name.string()); } else { - ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId, name.string(), - device->getSources()); + ALOGI("Device added: id=%d, name='%s', sources=0x%08x", deviceId, + identifier.name.string(), device->getSources()); } ssize_t deviceIndex = mDevices.indexOfKey(deviceId); @@ -392,8 +393,8 @@ void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) { } InputDevice* InputReader::createDeviceLocked(int32_t deviceId, - const String8& name, uint32_t classes) { - InputDevice* device = new InputDevice(&mContext, deviceId, name, classes); + const InputDeviceIdentifier& identifier, uint32_t classes) { + InputDevice* device = new InputDevice(&mContext, deviceId, identifier, classes); // External devices. if (classes & INPUT_DEVICE_CLASS_EXTERNAL) { @@ -851,9 +852,9 @@ bool InputReaderThread::threadLoop() { // --- InputDevice --- -InputDevice::InputDevice(InputReaderContext* context, int32_t id, const String8& name, - uint32_t classes) : - mContext(context), mId(id), mName(name), mClasses(classes), +InputDevice::InputDevice(InputReaderContext* context, int32_t id, + const InputDeviceIdentifier& identifier, uint32_t classes) : + mContext(context), mId(id), mIdentifier(identifier), mClasses(classes), mSources(0), mIsExternal(false), mDropUntilNextSync(false) { } @@ -961,7 +962,7 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) { #endif } } else if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_DROPPED) { - ALOGI("Detected input event buffer overrun for device %s.", mName.string()); + ALOGI("Detected input event buffer overrun for device %s.", getName().string()); mDropUntilNextSync = true; reset(rawEvent->when); } else { @@ -982,7 +983,7 @@ void InputDevice::timeoutExpired(nsecs_t when) { } void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) { - outDeviceInfo->initialize(mId, mName); + outDeviceInfo->initialize(mId, mIdentifier.name, mIdentifier.descriptor); size_t numMappers = mMappers.size(); for (size_t i = 0; i < numMappers; i++) { diff --git a/services/input/InputReader.h b/services/input/InputReader.h index 9bbe49c..8520a75 100644 --- a/services/input/InputReader.h +++ b/services/input/InputReader.h @@ -338,7 +338,7 @@ public: protected: // These members are protected so they can be instrumented by test cases. virtual InputDevice* createDeviceLocked(int32_t deviceId, - const String8& name, uint32_t classes); + const InputDeviceIdentifier& identifier, uint32_t classes); class ContextImpl : public InputReaderContext { InputReader* mReader; @@ -432,12 +432,13 @@ private: /* Represents the state of a single input device. */ class InputDevice { public: - InputDevice(InputReaderContext* context, int32_t id, const String8& name, uint32_t classes); + InputDevice(InputReaderContext* context, int32_t id, + const InputDeviceIdentifier& identifier, uint32_t classes); ~InputDevice(); inline InputReaderContext* getContext() { return mContext; } inline int32_t getId() { return mId; } - inline const String8& getName() { return mName; } + inline const String8& getName() { return mIdentifier.name; } inline uint32_t getClasses() { return mClasses; } inline uint32_t getSources() { return mSources; } @@ -486,7 +487,7 @@ public: private: InputReaderContext* mContext; int32_t mId; - String8 mName; + InputDeviceIdentifier mIdentifier; uint32_t mClasses; Vector<InputMapper*> mMappers; diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp index 08efe7d..2cccf9f 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/services/input/tests/InputReader_test.cpp @@ -274,7 +274,7 @@ class FakeEventHub : public EventHubInterface { }; struct Device { - String8 name; + InputDeviceIdentifier identifier; uint32_t classes; PropertyMap configuration; KeyedVector<int, RawAbsoluteAxisInfo> absoluteAxes; @@ -287,8 +287,8 @@ class FakeEventHub : public EventHubInterface { KeyedVector<int32_t, bool> leds; Vector<VirtualKeyDefinition> virtualKeys; - Device(const String8& name, uint32_t classes) : - name(name), classes(classes) { + Device(uint32_t classes) : + classes(classes) { } }; @@ -307,7 +307,8 @@ public: FakeEventHub() { } void addDevice(int32_t deviceId, const String8& name, uint32_t classes) { - Device* device = new Device(name, classes); + Device* device = new Device(classes); + device->identifier.name = name; mDevices.add(deviceId, device); enqueueEvent(ARBITRARY_TIME, deviceId, EventHubInterface::DEVICE_ADDED, 0, 0, 0, 0); @@ -433,9 +434,9 @@ private: return device ? device->classes : 0; } - virtual String8 getDeviceName(int32_t deviceId) const { + virtual InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const { Device* device = getDevice(deviceId); - return device ? device->name : String8("unknown"); + return device ? device->identifier : InputDeviceIdentifier(); } virtual void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const { @@ -857,18 +858,20 @@ public: } InputDevice* newDevice(int32_t deviceId, const String8& name, uint32_t classes) { - return new InputDevice(&mContext, deviceId, name, classes); + InputDeviceIdentifier identifier; + identifier.name = name; + return new InputDevice(&mContext, deviceId, identifier, classes); } protected: virtual InputDevice* createDeviceLocked(int32_t deviceId, - const String8& name, uint32_t classes) { + const InputDeviceIdentifier& identifier, uint32_t classes) { if (mNextDevice) { InputDevice* device = mNextDevice; mNextDevice = NULL; return device; } - return InputReader::createDeviceLocked(deviceId, name, classes); + return InputReader::createDeviceLocked(deviceId, identifier, classes); } friend class InputReaderTest; @@ -1231,7 +1234,9 @@ protected: mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener); mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0); - mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME), DEVICE_CLASSES); + InputDeviceIdentifier identifier; + identifier.name = DEVICE_NAME; + mDevice = new InputDevice(mFakeContext, DEVICE_ID, identifier, DEVICE_CLASSES); } virtual void TearDown() { @@ -1411,7 +1416,9 @@ protected: mFakePolicy = new FakeInputReaderPolicy(); mFakeListener = new FakeInputListener(); mFakeContext = new FakeInputReaderContext(mFakeEventHub, mFakePolicy, mFakeListener); - mDevice = new InputDevice(mFakeContext, DEVICE_ID, String8(DEVICE_NAME), DEVICE_CLASSES); + InputDeviceIdentifier identifier; + identifier.name = DEVICE_NAME; + mDevice = new InputDevice(mFakeContext, DEVICE_ID, identifier, DEVICE_CLASSES); mFakeEventHub->addDevice(DEVICE_ID, String8(DEVICE_NAME), 0); } diff --git a/services/java/com/android/server/AlarmManagerService.java b/services/java/com/android/server/AlarmManagerService.java index 0574405..32ac8e1 100644 --- a/services/java/com/android/server/AlarmManagerService.java +++ b/services/java/com/android/server/AlarmManagerService.java @@ -34,9 +34,9 @@ import android.os.Message; import android.os.PowerManager; import android.os.SystemClock; import android.os.SystemProperties; +import android.os.WorkSource; import android.text.TextUtils; import android.text.format.Time; -import android.util.EventLog; import android.util.Slog; import android.util.TimeUtils; @@ -50,6 +50,7 @@ import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedList; import java.util.Map; import java.util.TimeZone; @@ -89,6 +90,7 @@ class AlarmManagerService extends IAlarmManager.Stub { private int mDescriptor; private int mBroadcastRefCount = 0; private PowerManager.WakeLock mWakeLock; + private LinkedList<PendingIntent> mInFlight = new LinkedList<PendingIntent>(); private final AlarmThread mWaitThread = new AlarmThread(); private final AlarmHandler mHandler = new AlarmHandler(); private ClockReceiver mClockReceiver; @@ -668,10 +670,12 @@ class AlarmManagerService extends IAlarmManager.Stub { Intent.EXTRA_ALARM_COUNT, alarm.count), mResultReceiver, mHandler); - // we have an active broadcast so stay awake. + // we have an active broadcast so stay awake. if (mBroadcastRefCount == 0) { + setWakelockWorkSource(alarm.operation); mWakeLock.acquire(); } + mInFlight.add(alarm.operation); mBroadcastRefCount++; BroadcastStats bs = getStatsLocked(alarm.operation); @@ -700,7 +704,22 @@ class AlarmManagerService extends IAlarmManager.Stub { } } } - + + void setWakelockWorkSource(PendingIntent pi) { + try { + final int uid = ActivityManagerNative.getDefault() + .getUidForIntentSender(pi.getTarget()); + if (uid >= 0) { + mWakeLock.setWorkSource(new WorkSource(uid)); + return; + } + } catch (Exception e) { + } + + // Something went wrong; fall back to attributing the lock to the OS + mWakeLock.setWorkSource(null); + } + private class AlarmHandler extends Handler { public static final int ALARM_EVENT = 1; public static final int MINUTE_CHANGE_EVENT = 2; @@ -876,9 +895,20 @@ class AlarmManagerService extends IAlarmManager.Stub { fs.count++; } } + mInFlight.removeFirst(); mBroadcastRefCount--; if (mBroadcastRefCount == 0) { mWakeLock.release(); + } else { + // the next of our alarms is now in flight. reattribute the wakelock. + final PendingIntent nowInFlight = mInFlight.peekFirst(); + if (nowInFlight != null) { + setWakelockWorkSource(nowInFlight); + } else { + // should never happen + Slog.e(TAG, "Alarm wakelock still held but sent queue empty"); + mWakeLock.setWorkSource(null); + } } } } diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 2da827e..80e59cd 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -4444,6 +4444,17 @@ public final class ActivityManagerService extends ActivityManagerNative return null; } + public int getUidForIntentSender(IIntentSender sender) { + if (sender instanceof PendingIntentRecord) { + try { + PendingIntentRecord res = (PendingIntentRecord)sender; + return res.uid; + } catch (ClassCastException e) { + } + } + return -1; + } + public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) { if (!(pendingResult instanceof PendingIntentRecord)) { return false; diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index d60ff2b..a098f18 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -16,6 +16,7 @@ package com.android.server.am; +import com.android.internal.app.ResolverActivity; import com.android.server.AttributeCache; import com.android.server.am.ActivityStack.ActivityState; @@ -382,7 +383,7 @@ final class ActivityRecord { _intent.getData() == null && _intent.getType() == null && (intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0 && - !"android".equals(realActivity.getClassName())) { + !ResolverActivity.class.getName().equals(realActivity.getClassName())) { // This sure looks like a home activity! // Note the last check is so we don't count the resolver // activity as being home... really, we don't care about diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp index 22795bf..c57402f 100644 --- a/services/jni/com_android_server_input_InputManagerService.cpp +++ b/services/jni/com_android_server_input_InputManagerService.cpp @@ -95,6 +95,7 @@ static struct { jfieldID mId; jfieldID mName; + jfieldID mDescriptor; jfieldID mSources; jfieldID mKeyboardType; jfieldID mKeyCharacterMapFile; @@ -1169,12 +1170,17 @@ static jobject nativeGetInputDevice(JNIEnv* env, } jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor); - if (! deviceObj) { + if (!deviceObj) { return NULL; } jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string()); - if (! deviceNameObj) { + if (!deviceNameObj) { + return NULL; + } + + jstring deviceDescriptorObj = env->NewStringUTF(deviceInfo.getDescriptor().string()); + if (!deviceDescriptorObj) { return NULL; } @@ -1185,6 +1191,7 @@ static jobject nativeGetInputDevice(JNIEnv* env, env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId()); env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj); + env->SetObjectField(deviceObj, gInputDeviceClassInfo.mDescriptor, deviceDescriptorObj); env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources()); env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType()); env->SetObjectField(deviceObj, gInputDeviceClassInfo.mKeyCharacterMapFile, fileStr); @@ -1445,6 +1452,9 @@ int register_android_server_InputManager(JNIEnv* env) { GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz, "mName", "Ljava/lang/String;"); + GET_FIELD_ID(gInputDeviceClassInfo.mDescriptor, gInputDeviceClassInfo.clazz, + "mDescriptor", "Ljava/lang/String;"); + GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz, "mSources", "I"); |