diff options
-rw-r--r-- | cmds/keystore/keystore.c | 95 | ||||
-rw-r--r-- | include/ui/EventHub.h | 24 | ||||
-rw-r--r-- | include/ui/Input.h | 4 | ||||
-rw-r--r-- | include/ui/InputReader.h | 10 | ||||
-rwxr-xr-x | include/ui/KeycodeLabels.h | 2 | ||||
-rw-r--r-- | include/utils/ZipFileRO.h | 11 | ||||
-rw-r--r-- | libs/ui/EventHub.cpp | 113 | ||||
-rw-r--r-- | libs/ui/InputDispatcher.cpp | 128 | ||||
-rw-r--r-- | libs/ui/InputReader.cpp | 35 | ||||
-rw-r--r-- | libs/utils/ZipFileRO.cpp | 26 |
10 files changed, 292 insertions, 156 deletions
diff --git a/cmds/keystore/keystore.c b/cmds/keystore/keystore.c index 971a177..afa64f8 100644 --- a/cmds/keystore/keystore.c +++ b/cmds/keystore/keystore.c @@ -143,15 +143,20 @@ static void send_message(uint8_t *message, int length) send(the_socket, message, length, 0); } -/* Here is the file format. Values are encrypted by AES CBC, and MD5 is used to - * compute their checksums. To make the files portable, the length is stored in - * network order. Note that the first four bytes are reserved for future use and - * are always set to zero in this implementation. */ +/* Here is the file format. There are two parts in blob.value, the secret and + * the description. The secret is stored in ciphertext, and its original size + * can be found in blob.length. The description is stored after the secret in + * plaintext, and its size is specified in blob.info. The total size of the two + * parts must be no more than VALUE_SIZE bytes. The first three bytes of the + * file are reserved for future use and are always set to zero. Fields other + * than blob.info, blob.length, and blob.value are modified by encrypt_blob() + * and decrypt_blob(). Thus they should not be accessed from outside. */ static int the_entropy = -1; static struct __attribute__((packed)) { - uint32_t reserved; + uint8_t reserved[3]; + uint8_t info; uint8_t vector[AES_BLOCK_SIZE]; uint8_t encrypted[0]; uint8_t digest[MD5_DIGEST_LENGTH]; @@ -170,9 +175,13 @@ static int8_t encrypt_blob(char *name, AES_KEY *aes_key) return SYSTEM_ERROR; } - length = blob.length + blob.value - blob.encrypted; + length = blob.length + (blob.value - blob.encrypted); length = (length + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE * AES_BLOCK_SIZE; + if (blob.info != 0) { + memmove(&blob.encrypted[length], &blob.value[blob.length], blob.info); + } + blob.length = htonl(blob.length); MD5(blob.digested, length - (blob.digested - blob.encrypted), blob.digest); @@ -180,8 +189,8 @@ static int8_t encrypt_blob(char *name, AES_KEY *aes_key) AES_cbc_encrypt(blob.encrypted, blob.encrypted, length, aes_key, vector, AES_ENCRYPT); - blob.reserved = 0; - length += blob.encrypted - (uint8_t *)&blob; + memset(blob.reserved, 0, sizeof(blob.reserved)); + length += (blob.encrypted - (uint8_t *)&blob) + blob.info; fd = open(".tmp", O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR); length -= write(fd, &blob, length); @@ -200,7 +209,7 @@ static int8_t decrypt_blob(char *name, AES_KEY *aes_key) length = read(fd, &blob, sizeof(blob)); close(fd); - length -= blob.encrypted - (uint8_t *)&blob; + length -= (blob.encrypted - (uint8_t *)&blob) + blob.info; if (length < blob.value - blob.encrypted || length % AES_BLOCK_SIZE != 0) { return VALUE_CORRUPTED; } @@ -215,8 +224,13 @@ static int8_t decrypt_blob(char *name, AES_KEY *aes_key) length -= blob.value - blob.digested; blob.length = ntohl(blob.length); - return (blob.length < 0 || blob.length > length) ? VALUE_CORRUPTED : - NO_ERROR; + if (blob.length < 0 || blob.length > length) { + return VALUE_CORRUPTED; + } + if (blob.info != 0) { + memmove(&blob.value[blob.length], &blob.value[length], blob.info); + } + return NO_ERROR; } /* Here are the actions. Each of them is a function without arguments. All @@ -266,6 +280,7 @@ static int8_t insert() char name[NAME_MAX]; int n = sprintf(name, "%u_", uid); encode_key(&name[n], params[0].value, params[0].length); + blob.info = 0; blob.length = params[1].length; memcpy(blob.value, params[1].value, params[1].length); return encrypt_blob(name, &encryption_key); @@ -336,56 +351,88 @@ static int8_t reset() #define MASTER_KEY_FILE ".masterkey" #define MASTER_KEY_SIZE 16 +#define SALT_SIZE 16 -static void generate_key(uint8_t *key, uint8_t *password, int length) +static void set_key(uint8_t *key, uint8_t *password, int length, uint8_t *salt) { - PKCS5_PBKDF2_HMAC_SHA1((char *)password, length, (uint8_t *)"keystore", - sizeof("keystore"), 1024, MASTER_KEY_SIZE, key); + if (salt) { + PKCS5_PBKDF2_HMAC_SHA1((char *)password, length, salt, SALT_SIZE, + 8192, MASTER_KEY_SIZE, key); + } else { + PKCS5_PBKDF2_HMAC_SHA1((char *)password, length, (uint8_t *)"keystore", + sizeof("keystore"), 1024, MASTER_KEY_SIZE, key); + } } +/* Here is the history. To improve the security, the parameters to generate the + * master key has been changed. To make a seamless transition, we update the + * file using the same password when the user unlock it for the first time. If + * any thing goes wrong during the transition, the new file will not overwrite + * the old one. This avoids permanent damages of the existing data. */ + static int8_t password() { uint8_t key[MASTER_KEY_SIZE]; AES_KEY aes_key; - int n; + int8_t response = SYSTEM_ERROR; if (state == UNINITIALIZED) { - blob.length = MASTER_KEY_SIZE; if (read(the_entropy, blob.value, MASTER_KEY_SIZE) != MASTER_KEY_SIZE) { return SYSTEM_ERROR; } } else { - generate_key(key, params[0].value, params[0].length); + int fd = open(MASTER_KEY_FILE, O_RDONLY); + uint8_t *salt = NULL; + if (fd != -1) { + int length = read(fd, &blob, sizeof(blob)); + close(fd); + if (length > SALT_SIZE && blob.info == SALT_SIZE) { + salt = (uint8_t *)&blob + length - SALT_SIZE; + } + } + + set_key(key, params[0].value, params[0].length, salt); AES_set_decrypt_key(key, MASTER_KEY_SIZE * 8, &aes_key); - n = decrypt_blob(MASTER_KEY_FILE, &aes_key); - if (n == SYSTEM_ERROR) { + response = decrypt_blob(MASTER_KEY_FILE, &aes_key); + if (response == SYSTEM_ERROR) { return SYSTEM_ERROR; } - if (n != NO_ERROR || blob.length != MASTER_KEY_SIZE) { + if (response != NO_ERROR || blob.length != MASTER_KEY_SIZE) { if (retry <= 0) { reset(); return UNINITIALIZED; } return WRONG_PASSWORD + --retry; } + + if (!salt && params[1].length == -1) { + params[1] = params[0]; + } } if (params[1].length == -1) { memcpy(key, blob.value, MASTER_KEY_SIZE); } else { - generate_key(key, params[1].value, params[1].length); + uint8_t *salt = &blob.value[MASTER_KEY_SIZE]; + if (read(the_entropy, salt, SALT_SIZE) != SALT_SIZE) { + return SYSTEM_ERROR; + } + + set_key(key, params[1].value, params[1].length, salt); AES_set_encrypt_key(key, MASTER_KEY_SIZE * 8, &aes_key); memcpy(key, blob.value, MASTER_KEY_SIZE); - n = encrypt_blob(MASTER_KEY_FILE, &aes_key); + blob.info = SALT_SIZE; + blob.length = MASTER_KEY_SIZE; + response = encrypt_blob(MASTER_KEY_FILE, &aes_key); } - if (n == NO_ERROR) { + if (response == NO_ERROR) { AES_set_encrypt_key(key, MASTER_KEY_SIZE * 8, &encryption_key); AES_set_decrypt_key(key, MASTER_KEY_SIZE * 8, &decryption_key); state = NO_ERROR; retry = MAX_RETRY; } - return n; + return response; } static int8_t lock() diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h index d6b09dc..d78e35f 100644 --- a/include/ui/EventHub.h +++ b/include/ui/EventHub.h @@ -142,8 +142,13 @@ protected: public: // Synthetic raw event type codes produced when devices are added or removed. enum { + // Sent when a device is added. DEVICE_ADDED = 0x10000000, - DEVICE_REMOVED = 0x20000000 + // Sent when a device is removed. + DEVICE_REMOVED = 0x20000000, + // Sent when all added/removed devices from the most recent scan have been reported. + // This event is always sent at least once. + FINISHED_DEVICE_SCAN = 0x30000000, }; virtual uint32_t getDeviceClasses(int32_t deviceId) const = 0; @@ -181,6 +186,8 @@ public: */ virtual bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const = 0; + + virtual void dump(String8& dump) = 0; }; class EventHub : public EventHubInterface @@ -211,16 +218,18 @@ public: virtual bool getEvent(RawEvent* outEvent); + virtual void dump(String8& dump); + protected: virtual ~EventHub(); private: bool openPlatformInput(void); - int open_device(const char *device); - int close_device(const char *device); - int scan_dir(const char *dirname); - int read_notify(int nfd); + int openDevice(const char *device); + int closeDevice(const char *device); + int scanDir(const char *dirname); + int readNotify(int nfd); status_t mError; @@ -239,8 +248,8 @@ private: ~device_t(); }; - device_t* getDevice(int32_t deviceId) const; - bool hasKeycode(device_t* device, int keycode) const; + device_t* getDeviceLocked(int32_t deviceId) const; + bool hasKeycodeLocked(device_t* device, int keycode) const; int32_t getScanCodeStateLocked(device_t* device, int32_t scanCode) const; int32_t getKeyCodeStateLocked(device_t* device, int32_t keyCode) const; @@ -269,6 +278,7 @@ private: int mFDCount; bool mOpened; + bool mNeedToSendFinishedDeviceScan; List<String8> mExcludedDevices; // device ids that report particular switches. diff --git a/include/ui/Input.h b/include/ui/Input.h index 21baf32..ee40b85 100644 --- a/include/ui/Input.h +++ b/include/ui/Input.h @@ -73,7 +73,8 @@ namespace android { * policy decisions such as waking from device sleep. */ enum { - /* These flags originate in RawEvents and are generally set in the key map. */ + /* These flags originate in RawEvents and are generally set in the key map. + * See also labels for policy flags in KeycodeLabels.h. */ POLICY_FLAG_WAKE = 0x00000001, POLICY_FLAG_WAKE_DROPPED = 0x00000002, @@ -83,6 +84,7 @@ enum { POLICY_FLAG_ALT_GR = 0x00000020, POLICY_FLAG_MENU = 0x00000040, POLICY_FLAG_LAUNCHER = 0x00000080, + POLICY_FLAG_VIRTUAL = 0x00000100, POLICY_FLAG_RAW_MASK = 0x0000ffff, diff --git a/include/ui/InputReader.h b/include/ui/InputReader.h index d3fbaf7..3619189 100644 --- a/include/ui/InputReader.h +++ b/include/ui/InputReader.h @@ -103,10 +103,6 @@ public: virtual bool getDisplayInfo(int32_t displayId, int32_t* width, int32_t* height, int32_t* orientation) = 0; - /* Provides feedback for a virtual key down. - */ - virtual void virtualKeyDownFeedback() = 0; - /* Intercepts a key event. * The policy can use this method as an opportunity to perform power management functions * and early event preprocessing such as updating policy flags. @@ -283,14 +279,14 @@ private: // low-level input event decoding and device management void process(const RawEvent* rawEvent); - void addDevice(nsecs_t when, int32_t deviceId); - void removeDevice(nsecs_t when, int32_t deviceId); + void addDevice(int32_t deviceId); + void removeDevice(int32_t deviceId); InputDevice* createDevice(int32_t deviceId, const String8& name, uint32_t classes); void configureExcludedDevices(); void consumeEvent(const RawEvent* rawEvent); - void handleConfigurationChanged(nsecs_t when); + void handleConfigurationChanged(); // state management for all devices Mutex mStateLock; diff --git a/include/ui/KeycodeLabels.h b/include/ui/KeycodeLabels.h index c8d6ffc..f71d9cd 100755 --- a/include/ui/KeycodeLabels.h +++ b/include/ui/KeycodeLabels.h @@ -142,6 +142,7 @@ static const KeycodeLabel KEYCODES[] = { { NULL, 0 } }; +// See also policy flags in Input.h. static const KeycodeLabel FLAGS[] = { { "WAKE", 0x00000001 }, { "WAKE_DROPPED", 0x00000002 }, @@ -151,6 +152,7 @@ static const KeycodeLabel FLAGS[] = { { "ALT_GR", 0x00000020 }, { "MENU", 0x00000040 }, { "LAUNCHER", 0x00000080 }, + { "VIRTUAL", 0x00000100 }, { NULL, 0 } }; diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h index 9668bde..e1ff780 100644 --- a/include/utils/ZipFileRO.h +++ b/include/utils/ZipFileRO.h @@ -64,15 +64,8 @@ public: mNumEntries(-1), mDirectoryOffset(-1), mHashTableSize(-1), mHashTable(NULL) {} - ~ZipFileRO() { - free(mHashTable); - if (mDirectoryMap) - mDirectoryMap->release(); - if (mFd >= 0) - close(mFd); - if (mFileName) - free(mFileName); - } + + ~ZipFileRO(); /* * Open an archive. diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp index 1d38b4b..c0be3a0 100644 --- a/libs/ui/EventHub.cpp +++ b/libs/ui/EventHub.cpp @@ -73,6 +73,10 @@ #define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */ #endif +#define INDENT " " +#define INDENT2 " " +#define INDENT3 " " + namespace android { static const char *WAKE_LOCK_ID = "KeyEvents"; @@ -84,6 +88,10 @@ static inline int max(int v1, int v2) return (v1 > v2) ? v1 : v2; } +static inline const char* toString(bool value) { + return value ? "true" : "false"; +} + EventHub::device_t::device_t(int32_t _id, const char* _path, const char* name) : id(_id), path(_path), name(name), classes(0) , keyBitmask(NULL), layoutMap(new KeyLayoutMap()), fd(-1), next(NULL) { @@ -98,7 +106,7 @@ EventHub::EventHub(void) : mError(NO_INIT), mHaveFirstKeyboard(false), mFirstKeyboardId(0) , mDevicesById(0), mNumDevicesById(0) , mOpeningDevices(0), mClosingDevices(0) - , mDevices(0), mFDs(0), mFDCount(0), mOpened(false) + , mDevices(0), mFDs(0), mFDCount(0), mOpened(false), mNeedToSendFinishedDeviceScan(false) , mInputBufferIndex(0), mInputBufferCount(0), mInputDeviceIndex(0) { acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_ID); @@ -124,7 +132,7 @@ status_t EventHub::errorCheck() const String8 EventHub::getDeviceName(int32_t deviceId) const { AutoMutex _l(mLock); - device_t* device = getDevice(deviceId); + device_t* device = getDeviceLocked(deviceId); if (device == NULL) return String8(); return device->name; } @@ -132,7 +140,7 @@ String8 EventHub::getDeviceName(int32_t deviceId) const uint32_t EventHub::getDeviceClasses(int32_t deviceId) const { AutoMutex _l(mLock); - device_t* device = getDevice(deviceId); + device_t* device = getDeviceLocked(deviceId); if (device == NULL) return 0; return device->classes; } @@ -142,7 +150,7 @@ status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis, outAxisInfo->clear(); AutoMutex _l(mLock); - device_t* device = getDevice(deviceId); + device_t* device = getDeviceLocked(deviceId); if (device == NULL) return -1; struct input_absinfo info; @@ -167,7 +175,7 @@ int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const { if (scanCode >= 0 && scanCode <= KEY_MAX) { AutoMutex _l(mLock); - device_t* device = getDevice(deviceId); + device_t* device = getDeviceLocked(deviceId); if (device != NULL) { return getScanCodeStateLocked(device, scanCode); } @@ -188,7 +196,7 @@ int32_t EventHub::getScanCodeStateLocked(device_t* device, int32_t scanCode) con int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const { AutoMutex _l(mLock); - device_t* device = getDevice(deviceId); + device_t* device = getDeviceLocked(deviceId); if (device != NULL) { return getKeyCodeStateLocked(device, keyCode); } @@ -225,7 +233,7 @@ int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const { if (sw >= 0 && sw <= SW_MAX) { AutoMutex _l(mLock); - device_t* device = getDevice(deviceId); + device_t* device = getDeviceLocked(deviceId); if (device != NULL) { return getSwitchStateLocked(device, sw); } @@ -248,7 +256,7 @@ bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const { AutoMutex _l(mLock); - device_t* device = getDevice(deviceId); + device_t* device = getDeviceLocked(deviceId); if (device != NULL) { return markSupportedKeyCodesLocked(device, numCodes, keyCodes, outFlags); } @@ -284,7 +292,7 @@ status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode, int32_t* outKeycode, uint32_t* outFlags) const { AutoMutex _l(mLock); - device_t* device = getDevice(deviceId); + device_t* device = getDeviceLocked(deviceId); if (device != NULL && device->layoutMap != NULL) { status_t err = device->layoutMap->map(scancode, outKeycode, outFlags); @@ -294,7 +302,7 @@ status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode, } if (mHaveFirstKeyboard) { - device = getDevice(mFirstKeyboardId); + device = getDeviceLocked(mFirstKeyboardId); if (device != NULL && device->layoutMap != NULL) { status_t err = device->layoutMap->map(scancode, outKeycode, outFlags); @@ -311,11 +319,13 @@ status_t EventHub::scancodeToKeycode(int32_t deviceId, int scancode, void EventHub::addExcludedDevice(const char* deviceName) { + AutoMutex _l(mLock); + String8 name(deviceName); mExcludedDevices.push_back(name); } -EventHub::device_t* EventHub::getDevice(int32_t deviceId) const +EventHub::device_t* EventHub::getDeviceLocked(int32_t deviceId) const { if (deviceId == 0) deviceId = mFirstKeyboardId; int32_t id = deviceId & ID_MASK; @@ -344,6 +354,7 @@ bool EventHub::getEvent(RawEvent* outEvent) if (!mOpened) { mError = openPlatformInput() ? NO_ERROR : UNKNOWN_ERROR; mOpened = true; + mNeedToSendFinishedDeviceScan = true; } for (;;) { @@ -360,6 +371,7 @@ bool EventHub::getEvent(RawEvent* outEvent) } outEvent->type = DEVICE_REMOVED; delete device; + mNeedToSendFinishedDeviceScan = true; return true; } @@ -374,6 +386,13 @@ bool EventHub::getEvent(RawEvent* outEvent) outEvent->deviceId = device->id; } outEvent->type = DEVICE_ADDED; + mNeedToSendFinishedDeviceScan = true; + return true; + } + + if (mNeedToSendFinishedDeviceScan) { + mNeedToSendFinishedDeviceScan = false; + outEvent->type = FINISHED_DEVICE_SCAN; return true; } @@ -441,10 +460,10 @@ bool EventHub::getEvent(RawEvent* outEvent) } } - // read_notify() will modify mFDs and mFDCount, so this must be done after + // readNotify() will modify mFDs and mFDCount, so this must be done after // processing all other events. if(mFDs[0].revents & POLLIN) { - read_notify(mFDs[0].fd); + readNotify(mFDs[0].fd); } // Poll for events. Mind the wake lock dance! @@ -500,10 +519,9 @@ bool EventHub::openPlatformInput(void) mFDs[0].fd = -1; #endif - res = scan_dir(device_path); + res = scanDir(device_path); if(res < 0) { LOGE("scan dir failed for %s\n", device_path); - //open_device("/dev/input/event0"); } return true; @@ -531,8 +549,7 @@ static const int32_t GAMEPAD_KEYCODES[] = { AKEYCODE_BUTTON_START, AKEYCODE_BUTTON_SELECT, AKEYCODE_BUTTON_MODE }; -int EventHub::open_device(const char *deviceName) -{ +int EventHub::openDevice(const char *deviceName) { int version; int fd; struct pollfd *new_mFDs; @@ -782,22 +799,22 @@ int EventHub::open_device(const char *deviceName) property_set(propName, name); // 'Q' key support = cheap test of whether this is an alpha-capable kbd - if (hasKeycode(device, AKEYCODE_Q)) { + if (hasKeycodeLocked(device, AKEYCODE_Q)) { device->classes |= INPUT_DEVICE_CLASS_ALPHAKEY; } // See if this device has a DPAD. - if (hasKeycode(device, AKEYCODE_DPAD_UP) && - hasKeycode(device, AKEYCODE_DPAD_DOWN) && - hasKeycode(device, AKEYCODE_DPAD_LEFT) && - hasKeycode(device, AKEYCODE_DPAD_RIGHT) && - hasKeycode(device, AKEYCODE_DPAD_CENTER)) { + if (hasKeycodeLocked(device, AKEYCODE_DPAD_UP) && + hasKeycodeLocked(device, AKEYCODE_DPAD_DOWN) && + hasKeycodeLocked(device, AKEYCODE_DPAD_LEFT) && + hasKeycodeLocked(device, AKEYCODE_DPAD_RIGHT) && + hasKeycodeLocked(device, AKEYCODE_DPAD_CENTER)) { device->classes |= INPUT_DEVICE_CLASS_DPAD; } // See if this device has a gamepad. for (size_t i = 0; i < sizeof(GAMEPAD_KEYCODES); i++) { - if (hasKeycode(device, GAMEPAD_KEYCODES[i])) { + if (hasKeycodeLocked(device, GAMEPAD_KEYCODES[i])) { device->classes |= INPUT_DEVICE_CLASS_GAMEPAD; break; } @@ -830,7 +847,7 @@ int EventHub::open_device(const char *deviceName) return 0; } -bool EventHub::hasKeycode(device_t* device, int keycode) const +bool EventHub::hasKeycodeLocked(device_t* device, int keycode) const { if (device->keyBitmask == NULL || device->layoutMap == NULL) { return false; @@ -849,10 +866,9 @@ bool EventHub::hasKeycode(device_t* device, int keycode) const return false; } -int EventHub::close_device(const char *deviceName) -{ +int EventHub::closeDevice(const char *deviceName) { AutoMutex _l(mLock); - + int i; for(i = 1; i < mFDCount; i++) { if(strcmp(mDevices[i]->path.string(), deviceName) == 0) { @@ -902,8 +918,7 @@ int EventHub::close_device(const char *deviceName) return -1; } -int EventHub::read_notify(int nfd) -{ +int EventHub::readNotify(int nfd) { #ifdef HAVE_INOTIFY int res; char devname[PATH_MAX]; @@ -913,7 +928,7 @@ int EventHub::read_notify(int nfd) int event_pos = 0; struct inotify_event *event; - LOGV("EventHub::read_notify nfd: %d\n", nfd); + LOGV("EventHub::readNotify nfd: %d\n", nfd); res = read(nfd, event_buf, sizeof(event_buf)); if(res < (int)sizeof(*event)) { if(errno == EINTR) @@ -933,10 +948,10 @@ int EventHub::read_notify(int nfd) if(event->len) { strcpy(filename, event->name); if(event->mask & IN_CREATE) { - open_device(devname); + openDevice(devname); } else { - close_device(devname); + closeDevice(devname); } } event_size = sizeof(*event) + event->len; @@ -948,7 +963,7 @@ int EventHub::read_notify(int nfd) } -int EventHub::scan_dir(const char *dirname) +int EventHub::scanDir(const char *dirname) { char devname[PATH_MAX]; char *filename; @@ -966,10 +981,38 @@ int EventHub::scan_dir(const char *dirname) (de->d_name[1] == '.' && de->d_name[2] == '\0'))) continue; strcpy(filename, de->d_name); - open_device(devname); + openDevice(devname); } closedir(dir); return 0; } +void EventHub::dump(String8& dump) { + dump.append("Event Hub State:\n"); + + { // acquire lock + AutoMutex _l(mLock); + + dump.appendFormat(INDENT "HaveFirstKeyboard: %s\n", toString(mHaveFirstKeyboard)); + dump.appendFormat(INDENT "FirstKeyboardId: 0x%x\n", mFirstKeyboardId); + + dump.append(INDENT "Devices:\n"); + + for (int i = 0; i < mNumDevicesById; i++) { + const device_t* device = mDevicesById[i].device; + if (device) { + if (mFirstKeyboardId == device->id) { + dump.appendFormat(INDENT2 "0x%x: %s (aka device 0 - first keyboard)\n", + device->id, device->name.string()); + } else { + dump.appendFormat(INDENT2 "0x%x: %s\n", device->id, device->name.string()); + } + dump.appendFormat(INDENT3 "Classes: 0x%08x\n", device->classes); + dump.appendFormat(INDENT3 "Path: %s\n", device->path.string()); + dump.appendFormat(INDENT3 "KeyLayoutFile: %s\n", device->keylayoutFilename.string()); + } + } + } // release lock +} + }; // namespace android diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp index 9544a95..aa54f82 100644 --- a/libs/ui/InputDispatcher.cpp +++ b/libs/ui/InputDispatcher.cpp @@ -46,6 +46,9 @@ #include <errno.h> #include <limits.h> +#define INDENT " " +#define INDENT2 " " + namespace android { // Delay between reporting long touch events to the power manager. @@ -2490,74 +2493,96 @@ void InputDispatcher::logDispatchStateLocked() { } void InputDispatcher::dumpDispatchStateLocked(String8& dump) { - dump.appendFormat(" dispatchEnabled: %d\n", mDispatchEnabled); - dump.appendFormat(" dispatchFrozen: %d\n", mDispatchFrozen); + dump.appendFormat(INDENT "DispatchEnabled: %d\n", mDispatchEnabled); + dump.appendFormat(INDENT "DispatchFrozen: %d\n", mDispatchFrozen); if (mFocusedApplication) { - dump.appendFormat(" focusedApplication: name='%s', dispatchingTimeout=%0.3fms\n", + dump.appendFormat(INDENT "FocusedApplication: name='%s', dispatchingTimeout=%0.3fms\n", mFocusedApplication->name.string(), mFocusedApplication->dispatchingTimeout / 1000000.0); } else { - dump.append(" focusedApplication: <null>\n"); + dump.append(INDENT "FocusedApplication: <null>\n"); } - dump.appendFormat(" focusedWindow: name='%s'\n", + dump.appendFormat(INDENT "FocusedWindow: name='%s'\n", mFocusedWindow != NULL ? mFocusedWindow->name.string() : "<null>"); - dump.appendFormat(" touchState: down=%s, split=%s\n", toString(mTouchState.down), - toString(mTouchState.split)); - for (size_t i = 0; i < mTouchState.windows.size(); i++) { - const TouchedWindow& touchedWindow = mTouchState.windows[i]; - dump.appendFormat(" touchedWindow[%d]: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n", - i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value, - touchedWindow.targetFlags); - } - for (size_t i = 0; i < mWindows.size(); i++) { - dump.appendFormat(" windows[%d]: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, " - "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, " - "frame=[%d,%d][%d,%d], " - "visibleFrame=[%d,%d][%d,%d], " - "touchableArea=[%d,%d][%d,%d], " - "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n", - i, mWindows[i].name.string(), - toString(mWindows[i].paused), - toString(mWindows[i].hasFocus), - toString(mWindows[i].hasWallpaper), - toString(mWindows[i].visible), - toString(mWindows[i].canReceiveKeys), - mWindows[i].layoutParamsFlags, mWindows[i].layoutParamsType, - mWindows[i].layer, - mWindows[i].frameLeft, mWindows[i].frameTop, - mWindows[i].frameRight, mWindows[i].frameBottom, - mWindows[i].visibleFrameLeft, mWindows[i].visibleFrameTop, - mWindows[i].visibleFrameRight, mWindows[i].visibleFrameBottom, - mWindows[i].touchableAreaLeft, mWindows[i].touchableAreaTop, - mWindows[i].touchableAreaRight, mWindows[i].touchableAreaBottom, - mWindows[i].ownerPid, mWindows[i].ownerUid, - mWindows[i].dispatchingTimeout / 1000000.0); + + dump.appendFormat(INDENT "TouchDown: %s\n", toString(mTouchState.down)); + dump.appendFormat(INDENT "TouchSplit: %s\n", toString(mTouchState.split)); + if (!mTouchState.windows.isEmpty()) { + dump.append(INDENT "TouchedWindows:\n"); + for (size_t i = 0; i < mTouchState.windows.size(); i++) { + const TouchedWindow& touchedWindow = mTouchState.windows[i]; + dump.appendFormat(INDENT2 "%d: name='%s', pointerIds=0x%0x, targetFlags=0x%x\n", + i, touchedWindow.window->name.string(), touchedWindow.pointerIds.value, + touchedWindow.targetFlags); + } + } else { + dump.append(INDENT "TouchedWindows: <none>\n"); + } + + if (!mWindows.isEmpty()) { + dump.append(INDENT "Windows:\n"); + for (size_t i = 0; i < mWindows.size(); i++) { + const InputWindow& window = mWindows[i]; + dump.appendFormat(INDENT2 "%d: name='%s', paused=%s, hasFocus=%s, hasWallpaper=%s, " + "visible=%s, canReceiveKeys=%s, flags=0x%08x, type=0x%08x, layer=%d, " + "frame=[%d,%d][%d,%d], " + "visibleFrame=[%d,%d][%d,%d], " + "touchableArea=[%d,%d][%d,%d], " + "ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n", + i, window.name.string(), + toString(window.paused), + toString(window.hasFocus), + toString(window.hasWallpaper), + toString(window.visible), + toString(window.canReceiveKeys), + window.layoutParamsFlags, window.layoutParamsType, + window.layer, + window.frameLeft, window.frameTop, + window.frameRight, window.frameBottom, + window.visibleFrameLeft, window.visibleFrameTop, + window.visibleFrameRight, window.visibleFrameBottom, + window.touchableAreaLeft, window.touchableAreaTop, + window.touchableAreaRight, window.touchableAreaBottom, + window.ownerPid, window.ownerUid, + window.dispatchingTimeout / 1000000.0); + } + } else { + dump.append(INDENT "Windows: <none>\n"); } - for (size_t i = 0; i < mMonitoringChannels.size(); i++) { - const sp<InputChannel>& channel = mMonitoringChannels[i]; - dump.appendFormat(" monitoringChannel[%d]: '%s'\n", - i, channel->getName().string()); + if (!mMonitoringChannels.isEmpty()) { + dump.append(INDENT "MonitoringChannels:\n"); + for (size_t i = 0; i < mMonitoringChannels.size(); i++) { + const sp<InputChannel>& channel = mMonitoringChannels[i]; + dump.appendFormat(INDENT2 "%d: '%s'\n", i, channel->getName().string()); + } + } else { + dump.append(INDENT "MonitoringChannels: <none>\n"); } - dump.appendFormat(" inboundQueue: length=%u", mInboundQueue.count()); + dump.appendFormat(INDENT "InboundQueue: length=%u\n", mInboundQueue.count()); - for (size_t i = 0; i < mActiveConnections.size(); i++) { - const Connection* connection = mActiveConnections[i]; - dump.appendFormat(" activeConnection[%d]: '%s', status=%s, outboundQueueLength=%u" - "inputState.isNeutral=%s, inputState.isOutOfSync=%s\n", - i, connection->getInputChannelName(), connection->getStatusLabel(), - connection->outboundQueue.count(), - toString(connection->inputState.isNeutral()), - toString(connection->inputState.isOutOfSync())); + if (!mActiveConnections.isEmpty()) { + dump.append(INDENT "ActiveConnections:\n"); + for (size_t i = 0; i < mActiveConnections.size(); i++) { + const Connection* connection = mActiveConnections[i]; + dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u" + "inputState.isNeutral=%s, inputState.isOutOfSync=%s\n", + i, connection->getInputChannelName(), connection->getStatusLabel(), + connection->outboundQueue.count(), + toString(connection->inputState.isNeutral()), + toString(connection->inputState.isOutOfSync())); + } + } else { + dump.append(INDENT "ActiveConnections: <none>\n"); } if (isAppSwitchPendingLocked()) { - dump.appendFormat(" appSwitch: pending, due in %01.1fms\n", + dump.appendFormat(INDENT "AppSwitch: pending, due in %01.1fms\n", (mAppSwitchDueTime - now()) / 1000000.0); } else { - dump.append(" appSwitch: not pending\n"); + dump.append(INDENT "AppSwitch: not pending\n"); } } @@ -2774,6 +2799,7 @@ void InputDispatcher::updateDispatchStatisticsLocked(nsecs_t currentTime, const } void InputDispatcher::dump(String8& dump) { + dump.append("Input Dispatcher State:\n"); dumpDispatchStateLocked(dump); } diff --git a/libs/ui/InputReader.cpp b/libs/ui/InputReader.cpp index 1d35e10..8e173aa 100644 --- a/libs/ui/InputReader.cpp +++ b/libs/ui/InputReader.cpp @@ -226,11 +226,15 @@ void InputReader::loopOnce() { void InputReader::process(const RawEvent* rawEvent) { switch (rawEvent->type) { case EventHubInterface::DEVICE_ADDED: - addDevice(rawEvent->when, rawEvent->deviceId); + addDevice(rawEvent->deviceId); break; case EventHubInterface::DEVICE_REMOVED: - removeDevice(rawEvent->when, rawEvent->deviceId); + removeDevice(rawEvent->deviceId); + break; + + case EventHubInterface::FINISHED_DEVICE_SCAN: + handleConfigurationChanged(); break; default: @@ -239,7 +243,7 @@ void InputReader::process(const RawEvent* rawEvent) { } } -void InputReader::addDevice(nsecs_t when, int32_t deviceId) { +void InputReader::addDevice(int32_t deviceId) { String8 name = mEventHub->getDeviceName(deviceId); uint32_t classes = mEventHub->getDeviceClasses(deviceId); @@ -269,11 +273,9 @@ void InputReader::addDevice(nsecs_t when, int32_t deviceId) { delete device; return; } - - handleConfigurationChanged(when); } -void InputReader::removeDevice(nsecs_t when, int32_t deviceId) { +void InputReader::removeDevice(int32_t deviceId) { bool removed = false; InputDevice* device = NULL; { // acquire device registry writer lock @@ -303,8 +305,6 @@ void InputReader::removeDevice(nsecs_t when, int32_t deviceId) { device->reset(); delete device; - - handleConfigurationChanged(when); } InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) { @@ -372,7 +372,7 @@ void InputReader::consumeEvent(const RawEvent* rawEvent) { } // release device registry reader lock } -void InputReader::handleConfigurationChanged(nsecs_t when) { +void InputReader::handleConfigurationChanged() { // Reset global meta state because it depends on the list of all configured devices. updateGlobalMetaState(); @@ -380,6 +380,7 @@ void InputReader::handleConfigurationChanged(nsecs_t when) { updateInputConfiguration(); // Enqueue configuration changed. + nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC); mDispatcher->notifyConfigurationChanged(when); } @@ -575,6 +576,11 @@ bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, s } void InputReader::dump(String8& dump) { + mEventHub->dump(dump); + dump.append("\n"); + + dump.append("Input Reader State:\n"); + { // acquire device registry reader lock RWLock::AutoRLock _rl(mDeviceRegistryLock); @@ -861,7 +867,6 @@ void KeyboardInputMapper::dump(String8& dump) { AutoMutex _l(mLock); dump.append(INDENT2 "Keyboard Input Mapper:\n"); dump.appendFormat(INDENT3 "AssociatedDisplayId: %d\n", mAssociatedDisplayId); - dump.appendFormat(INDENT3 "Sources: 0x%x\n", mSources); dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType); dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size()); dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState); @@ -993,7 +998,10 @@ void KeyboardInputMapper::applyPolicyAndDispatch(nsecs_t when, uint32_t policyFl int32_t keyEventAction = down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP; int32_t keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM; if (policyFlags & POLICY_FLAG_WOKE_HERE) { - keyEventFlags = keyEventFlags | AKEY_EVENT_FLAG_WOKE_HERE; + keyEventFlags |= AKEY_EVENT_FLAG_WOKE_HERE; + } + if (policyFlags & POLICY_FLAG_VIRTUAL) { + keyEventFlags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY; } getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags, @@ -2162,10 +2170,7 @@ void TouchInputMapper::applyPolicyAndDispatchVirtualKey(nsecs_t when, uint32_t p int32_t keyCode, int32_t scanCode, nsecs_t downTime) { int32_t metaState = mContext->getGlobalMetaState(); - if (keyEventAction == AKEY_EVENT_ACTION_DOWN) { - getPolicy()->virtualKeyDownFeedback(); - } - + policyFlags |= POLICY_FLAG_VIRTUAL; int32_t policyActions = getPolicy()->interceptKey(when, getDeviceId(), keyEventAction == AKEY_EVENT_ACTION_DOWN, keyCode, scanCode, policyFlags); diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp index 9fcae72..bee86b2 100644 --- a/libs/utils/ZipFileRO.cpp +++ b/libs/utils/ZipFileRO.cpp @@ -86,6 +86,16 @@ using namespace android; */ #define kZipEntryAdj 10000 +ZipFileRO::~ZipFileRO() { + free(mHashTable); + if (mDirectoryMap) + mDirectoryMap->release(); + if (mFd >= 0) + TEMP_FAILURE_RETRY(close(mFd)); + if (mFileName) + free(mFileName); +} + /* * Convert a ZipEntryRO to a hash table index, verifying that it's in a * valid range. @@ -122,7 +132,7 @@ status_t ZipFileRO::open(const char* zipFileName) mFileLength = lseek(fd, 0, SEEK_END); if (mFileLength < kEOCDLen) { - close(fd); + TEMP_FAILURE_RETRY(close(fd)); return UNKNOWN_ERROR; } @@ -152,7 +162,7 @@ status_t ZipFileRO::open(const char* zipFileName) bail: free(mFileName); mFileName = NULL; - close(fd); + TEMP_FAILURE_RETRY(close(fd)); return UNKNOWN_ERROR; } @@ -512,12 +522,14 @@ bool ZipFileRO::getEntryInfo(ZipEntryRO entry, int* pMethod, size_t* pUncompLen, LOGW("failed reading lfh from offset %ld\n", localHdrOffset); return false; } - } - if (get4LE(lfhBuf) != kLFHSignature) { - LOGW("didn't find signature at start of lfh, offset=%ld (got 0x%08lx, expected 0x%08x)\n", - localHdrOffset, get4LE(lfhBuf), kLFHSignature); - return false; + if (get4LE(lfhBuf) != kLFHSignature) { + off_t actualOffset = lseek(mFd, 0, SEEK_CUR); + LOGW("didn't find signature at start of lfh; wanted: offset=%ld data=0x%08x; " + "got: offset=%zd data=0x%08lx\n", + localHdrOffset, kLFHSignature, (size_t)actualOffset, get4LE(lfhBuf)); + return false; + } } off_t dataOffset = localHdrOffset + kLFHLen |