diff options
34 files changed, 406 insertions, 271 deletions
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp index 9def406..26c5b4a 100644 --- a/cmds/atrace/atrace.cpp +++ b/cmds/atrace/atrace.cpp @@ -264,9 +264,27 @@ static bool appendStr(const char* filename, const char* str) static void writeClockSyncMarker() { char buffer[128]; + int len = 0; + int fd = open(k_traceMarkerPath, O_WRONLY); + if (fd == -1) { + fprintf(stderr, "error opening %s: %s (%d)\n", k_traceMarkerPath, + strerror(errno), errno); + return; + } float now_in_seconds = systemTime(CLOCK_MONOTONIC) / 1000000000.0f; - snprintf(buffer, 128, "trace_event_clock_sync: parent_ts=%f\n", now_in_seconds); - writeStr(k_traceMarkerPath, buffer); + + len = snprintf(buffer, 128, "trace_event_clock_sync: parent_ts=%f\n", now_in_seconds); + if (write(fd, buffer, len) != len) { + fprintf(stderr, "error writing clock sync marker %s (%d)\n", strerror(errno), errno); + } + + int64_t realtime_in_ms = systemTime(CLOCK_REALTIME) / 1000000; + len = snprintf(buffer, 128, "trace_event_clock_sync: realtime_ts=%" PRId64 "\n", realtime_in_ms); + if (write(fd, buffer, len) != len) { + fprintf(stderr, "error writing clock sync marker %s (%d)\n", strerror(errno), errno); + } + + close(fd); } // Enable or disable a kernel option by writing a "1" or a "0" into a /sys @@ -646,7 +664,6 @@ static bool startTrace() // Disable tracing in the kernel. static void stopTrace() { - writeClockSyncMarker(); setTracingEnabled(false); } @@ -940,6 +957,7 @@ int main(int argc, char **argv) // another. ok = clearTrace(); + writeClockSyncMarker(); if (ok && !async) { // Sleep to allow the trace to be captured. struct timespec timeLeft; diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c index 0aa8fe9..b88b605 100644 --- a/cmds/dumpstate/dumpstate.c +++ b/cmds/dumpstate/dumpstate.c @@ -351,7 +351,7 @@ static void dumpstate() { run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL); - run_command("RAFT LOGS", 300, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL); + run_command("RAFT LOGS", 600, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL); /* show the traces we collected in main(), if that was done */ if (dump_traces_path != NULL) { @@ -437,8 +437,6 @@ static void dumpstate() { run_command("ARP CACHE", 10, "ip", "-4", "neigh", "show", NULL); run_command("IPv6 ND CACHE", 10, "ip", "-6", "neigh", "show", NULL); - run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL); - run_command("IPTABLES", 10, SU_PATH, "root", "iptables", "-L", "-nvx", NULL); run_command("IP6TABLES", 10, SU_PATH, "root", "ip6tables", "-L", "-nvx", NULL); run_command("IPTABLE NAT", 10, SU_PATH, "root", "iptables", "-t", "nat", "-L", "-nvx", NULL); @@ -450,25 +448,29 @@ static void dumpstate() { SU_PATH, "root", "wpa_cli", "IFNAME=wlan0", "list_networks", NULL); #ifdef FWDUMP_bcmdhd - run_command("DUMP WIFI INTERNAL COUNTERS", 20, + run_command("ND OFFLOAD TABLE", 5, + SU_PATH, "root", "wlutil", "nd_hostip", NULL); + + run_command("DUMP WIFI INTERNAL COUNTERS (1)", 20, SU_PATH, "root", "wlutil", "counters", NULL); + + run_command("ND OFFLOAD STATUS (1)", 5, + SU_PATH, "root", "wlutil", "nd_status", NULL); + #endif dump_file("INTERRUPTS (1)", "/proc/interrupts"); - property_get("dhcp.wlan0.gateway", network, ""); - if (network[0]) - run_command("PING GATEWAY", 10, "ping", "-c", "3", "-i", ".5", network, NULL); - property_get("dhcp.wlan0.dns1", network, ""); - if (network[0]) - run_command("PING DNS1", 10, "ping", "-c", "3", "-i", ".5", network, NULL); - property_get("dhcp.wlan0.dns2", network, ""); - if (network[0]) - run_command("PING DNS2", 10, "ping", "-c", "3", "-i", ".5", network, NULL); + run_command("NETWORK DIAGNOSTICS", 10, "dumpsys", "connectivity", "--diag", NULL); + #ifdef FWDUMP_bcmdhd run_command("DUMP WIFI STATUS", 20, SU_PATH, "root", "dhdutil", "-i", "wlan0", "dump", NULL); - run_command("DUMP WIFI INTERNAL COUNTERS", 20, + + run_command("DUMP WIFI INTERNAL COUNTERS (2)", 20, SU_PATH, "root", "wlutil", "counters", NULL); + + run_command("ND OFFLOAD STATUS (2)", 5, + SU_PATH, "root", "wlutil", "nd_status", NULL); #endif dump_file("INTERRUPTS (2)", "/proc/interrupts"); diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp index 7090b36..c05a3d3 100644 --- a/cmds/installd/commands.cpp +++ b/cmds/installd/commands.cpp @@ -746,7 +746,7 @@ static bool check_boolean_property(const char* property_name, bool default_value static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name, const char* output_file_name, int swap_fd, const char *pkgname, const char *instruction_set, - bool vm_safe_mode, bool debuggable) + bool vm_safe_mode, bool debuggable, bool post_bootcomplete) { static const unsigned int MAX_INSTRUCTION_SET_LEN = 7; @@ -770,7 +770,10 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name, dex2oat_compiler_filter_flag, NULL) > 0; char dex2oat_threads_buf[PROPERTY_VALUE_MAX]; - bool have_dex2oat_threads_flag = property_get("dalvik.vm.dex2oat-threads", dex2oat_threads_buf, + bool have_dex2oat_threads_flag = property_get(post_bootcomplete + ? "dalvik.vm.dex2oat-threads" + : "dalvik.vm.boot-dex2oat-threads", + dex2oat_threads_buf, NULL) > 0; char dex2oat_threads_arg[PROPERTY_VALUE_MAX + 2]; if (have_dex2oat_threads_flag) { @@ -1065,9 +1068,22 @@ static bool calculate_odex_file_path(char path[PKG_PATH_MAX], return true; } +static void SetDex2OatAndPatchOatScheduling(bool set_to_bg) { + if (set_to_bg) { + if (set_sched_policy(0, SP_BACKGROUND) < 0) { + ALOGE("set_sched_policy failed: %s\n", strerror(errno)); + exit(70); + } + if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) { + ALOGE("setpriority failed: %s\n", strerror(errno)); + exit(71); + } + } +} + int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgname, const char *instruction_set, int dexopt_needed, - bool vm_safe_mode, bool debuggable, const char* oat_dir) + bool vm_safe_mode, bool debuggable, const char* oat_dir, bool boot_complete) { struct utimbuf ut; struct stat input_stat; @@ -1198,14 +1214,7 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, ALOGE("capset failed: %s\n", strerror(errno)); exit(66); } - if (set_sched_policy(0, SP_BACKGROUND) < 0) { - ALOGE("set_sched_policy failed: %s\n", strerror(errno)); - exit(70); - } - if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_BACKGROUND) < 0) { - ALOGE("setpriority failed: %s\n", strerror(errno)); - exit(71); - } + SetDex2OatAndPatchOatScheduling(boot_complete); if (flock(out_fd, LOCK_EX | LOCK_NB) != 0) { ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno)); exit(67); @@ -1222,7 +1231,7 @@ int dexopt(const char *apk_path, uid_t uid, bool is_public, input_file_name++; } run_dex2oat(input_fd, out_fd, input_file_name, out_path, swap_fd, pkgname, - instruction_set, vm_safe_mode, debuggable); + instruction_set, vm_safe_mode, debuggable, boot_complete); } else { ALOGE("Invalid dexopt needed: %d\n", dexopt_needed); exit(73); diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp index 13e3168..f67e838 100644 --- a/cmds/installd/installd.cpp +++ b/cmds/installd/installd.cpp @@ -48,9 +48,9 @@ static int do_install(char **arg, char reply[REPLY_MAX] __unused) static int do_dexopt(char **arg, char reply[REPLY_MAX] __unused) { /* apk_path, uid, is_public, pkgname, instruction_set, - * dexopt_needed, vm_safe_mode, debuggable, oat_dir */ + * dexopt_needed, vm_safe_mode, debuggable, oat_dir, boot_complete */ return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4], atoi(arg[5]), - atoi(arg[6]), atoi(arg[7]), arg[8]); + atoi(arg[6]), atoi(arg[7]), arg[8], atoi(arg[9])); } static int do_mark_boot_complete(char **arg, char reply[REPLY_MAX] __unused) @@ -194,7 +194,7 @@ struct cmdinfo { struct cmdinfo cmds[] = { { "ping", 0, do_ping }, { "install", 5, do_install }, - { "dexopt", 9, do_dexopt }, + { "dexopt", 10, do_dexopt }, { "markbootcomplete", 1, do_mark_boot_complete }, { "movedex", 3, do_move_dex }, { "rmdex", 2, do_rm_dex }, diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index 7ec5793..24b9084 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -243,7 +243,7 @@ int get_size(const char *uuid, const char *pkgname, int userid, int free_cache(const char *uuid, int64_t free_size); int dexopt(const char *apk_path, uid_t uid, bool is_public, const char *pkgName, const char *instruction_set, int dexopt_needed, bool vm_safe_mode, - bool debuggable, const char* oat_dir); + bool debuggable, const char* oat_dir, bool boot_complete); int mark_boot_complete(const char *instruction_set); int movefiles(); int linklib(const char* uuid, const char* pkgname, const char* asecLibDir, int userId); diff --git a/data/etc/android.hardware.audio.pro.xml b/data/etc/android.hardware.audio.pro.xml new file mode 100644 index 0000000..5328d41 --- /dev/null +++ b/data/etc/android.hardware.audio.pro.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 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. +--> + +<!-- This is the feature indicating professional audio, as specified by the + CDD. ONLY devices that meet the CDD's requirements may declare this + feature. --> +<permissions> + <feature name="android.hardware.audio.pro" /> +</permissions> diff --git a/include/android/keycodes.h b/include/android/keycodes.h index 1f55d9f..421abe5 100644 --- a/include/android/keycodes.h +++ b/include/android/keycodes.h @@ -735,7 +735,9 @@ enum { AKEYCODE_MEDIA_SKIP_FORWARD = 272, AKEYCODE_MEDIA_SKIP_BACKWARD = 273, AKEYCODE_MEDIA_STEP_FORWARD = 274, - AKEYCODE_MEDIA_STEP_BACKWARD = 275 + AKEYCODE_MEDIA_STEP_BACKWARD = 275, + /** Put device to sleep unless a wakelock is held. */ + AKEYCODE_SOFT_SLEEP = 276 // NOTE: If you add a new keycode here you must also add it to several other files. // Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list. diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h index 3ada1e9..16cd6cf 100644 --- a/include/binder/Parcel.h +++ b/include/binder/Parcel.h @@ -341,10 +341,12 @@ public: }; private: - size_t mBlobAshmemSize; + size_t mOpenAshmemSize; public: + // TODO: Remove once ABI can be changed. size_t getBlobAshmemSize() const; + size_t getOpenAshmemSize() const; }; // --------------------------------------------------------------------------- diff --git a/include/input/Input.h b/include/input/Input.h index 4a67f47..617175b 100644 --- a/include/input/Input.h +++ b/include/input/Input.h @@ -28,6 +28,7 @@ #include <utils/String8.h> #include <utils/Timers.h> #include <utils/Vector.h> +#include <stdint.h> /* * Additional private constants not defined in ndk/ui/input.h. @@ -111,6 +112,11 @@ enum { #define MAX_POINTERS 16 /* + * Maximum number of samples supported per motion event. + */ +#define MAX_SAMPLES UINT16_MAX + +/* * Maximum pointer id value supported in a motion event. * Smallest pointer id is 0. * (This is limited by our use of BitSet32 to track pointer assignments.) diff --git a/include/input/InputEventLabels.h b/include/input/InputEventLabels.h index 344f2f3..f0a6238 100644 --- a/include/input/InputEventLabels.h +++ b/include/input/InputEventLabels.h @@ -311,6 +311,7 @@ static const InputEventLabel KEYCODES[] = { DEFINE_KEYCODE(MEDIA_SKIP_BACKWARD), DEFINE_KEYCODE(MEDIA_STEP_FORWARD), DEFINE_KEYCODE(MEDIA_STEP_BACKWARD), + DEFINE_KEYCODE(SOFT_SLEEP), { NULL, 0 } }; diff --git a/include/input/KeyCharacterMap.h b/include/input/KeyCharacterMap.h index e70666a..3f0914b 100644 --- a/include/input/KeyCharacterMap.h +++ b/include/input/KeyCharacterMap.h @@ -124,6 +124,11 @@ public: * the mapping in some way. */ status_t mapKey(int32_t scanCode, int32_t usageCode, int32_t* outKeyCode) const; + /* Tries to find a replacement key code for a given key code and meta state + * in character map. */ + void tryRemapKey(int32_t scanCode, int32_t metaState, + int32_t* outKeyCode, int32_t* outMetaState) const; + #if HAVE_ANDROID_OS /* Reads a key map from a parcel. */ static sp<KeyCharacterMap> readFromParcel(Parcel* parcel); @@ -151,6 +156,9 @@ private: /* The fallback keycode if the key is not handled. */ int32_t fallbackKeyCode; + + /* The replacement keycode if the key has to be replaced outright. */ + int32_t replacementKeyCode; }; struct Key { diff --git a/include/input/Keyboard.h b/include/input/Keyboard.h index 519bb22..d4903e9 100644 --- a/include/input/Keyboard.h +++ b/include/input/Keyboard.h @@ -88,6 +88,13 @@ extern bool isEligibleBuiltInKeyboard(const InputDeviceIdentifier& deviceIdentif extern int32_t updateMetaState(int32_t keyCode, bool down, int32_t oldMetaState); /** + * Normalizes the meta state such that if either the left or right modifier + * meta state bits are set then the result will also include the universal + * bit for that modifier. + */ +extern int32_t normalizeMetaState(int32_t oldMetaState); + +/** * Returns true if a key is a meta key like ALT or CAPS_LOCK. */ extern bool isMetaKey(int32_t keyCode); diff --git a/include/media/openmax/OMX_Core.h b/include/media/openmax/OMX_Core.h index 521c223..f746a69 100644 --- a/include/media/openmax/OMX_Core.h +++ b/include/media/openmax/OMX_Core.h @@ -509,7 +509,7 @@ typedef enum OMX_EVENTTYPE OMX_EventKhronosExtensions = 0x6F000000, /**< Reserved region for introducing Khronos Standard Extensions */ OMX_EventVendorStartUnused = 0x7F000000, /**< Reserved region for introducing Vendor Extensions */ - /** Event when tunneled decoder has rendered an output + /** Event when tunneled decoder has rendered an output or reached EOS * nData1 must contain the number of timestamps returned * pEventData must point to an array of the OMX_VIDEO_RENDEREVENTTYPE structs containing the * render-timestamps of each frame. Component may batch rendered timestamps using this event, @@ -518,6 +518,10 @@ typedef enum OMX_EVENTTYPE * * If component is doing frame-rate conversion, it must signal the render time of each * converted frame, and must interpolate media timestamps for in-between frames. + * + * When the component reached EOS, it must signal an EOS timestamp using the same mechanism. + * This is in addition to the timestamp of the last rendered frame, and should follow that + * frame. */ OMX_EventOutputRendered = 0x7F000001, OMX_EventMax = 0x7FFFFFFF diff --git a/include/media/openmax/OMX_VideoExt.h b/include/media/openmax/OMX_VideoExt.h index 34c0405..3971bc5 100644 --- a/include/media/openmax/OMX_VideoExt.h +++ b/include/media/openmax/OMX_VideoExt.h @@ -203,10 +203,17 @@ typedef struct OMX_VIDEO_SLICESEGMENTSTYPE { OMX_BOOL bEnableLoopFilterAcrossSlices; } OMX_VIDEO_SLICESEGMENTSTYPE; -/** Structure to return timestamps of rendered output frames for tunneled components */ +/** Structure to return timestamps of rendered output frames as well as EOS + * for tunneled components. + */ typedef struct OMX_VIDEO_RENDEREVENTTYPE { OMX_S64 nMediaTimeUs; // timestamp of rendered video frame OMX_S64 nSystemTimeNs; // system monotonic time at the time frame was rendered + // Use INT64_MAX for nMediaTimeUs to signal that the EOS + // has been reached. In this case, nSystemTimeNs MUST be + // the system time when the last frame was rendered. + // This MUST be done in addition to returning (and + // following) the render information for the last frame. } OMX_VIDEO_RENDEREVENTTYPE; #ifdef __cplusplus diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h index 799944f..ad73ee7 100644 --- a/include/ui/DisplayInfo.h +++ b/include/ui/DisplayInfo.h @@ -36,6 +36,7 @@ struct DisplayInfo { bool secure; nsecs_t appVsyncOffset; nsecs_t presentationDeadline; + int colorTransform; }; /* Display orientations as defined in Surface.java and ISurfaceComposer.h. */ diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 7a4ddc4..22d7ef3 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -96,7 +96,7 @@ enum { }; void acquire_object(const sp<ProcessState>& proc, - const flat_binder_object& obj, const void* who) + const flat_binder_object& obj, const void* who, size_t* outAshmemSize) { switch (obj.type) { case BINDER_TYPE_BINDER: @@ -123,8 +123,15 @@ void acquire_object(const sp<ProcessState>& proc, return; } case BINDER_TYPE_FD: { - // intentionally blank -- nothing to do to acquire this, but we do - // recognize it as a legitimate object type. + if (obj.cookie != 0) { + if (outAshmemSize != NULL) { + // If we own an ashmem fd, keep track of how much memory it refers to. + int size = ashmem_get_size_region(obj.handle); + if (size > 0) { + *outAshmemSize += size; + } + } + } return; } } @@ -132,9 +139,15 @@ void acquire_object(const sp<ProcessState>& proc, ALOGD("Invalid object type 0x%08x", obj.type); } -void release_object(const sp<ProcessState>& proc, +void acquire_object(const sp<ProcessState>& proc, const flat_binder_object& obj, const void* who) { + acquire_object(proc, obj, who, NULL); +} + +static void release_object(const sp<ProcessState>& proc, + const flat_binder_object& obj, const void* who, size_t* outAshmemSize) +{ switch (obj.type) { case BINDER_TYPE_BINDER: if (obj.binder) { @@ -160,7 +173,16 @@ void release_object(const sp<ProcessState>& proc, return; } case BINDER_TYPE_FD: { - if (obj.cookie != 0) close(obj.handle); + if (outAshmemSize != NULL) { + if (obj.cookie != 0) { + int size = ashmem_get_size_region(obj.handle); + if (size > 0) { + *outAshmemSize -= size; + } + + close(obj.handle); + } + } return; } } @@ -168,6 +190,12 @@ void release_object(const sp<ProcessState>& proc, ALOGE("Invalid object type 0x%08x", obj.type); } +void release_object(const sp<ProcessState>& proc, + const flat_binder_object& obj, const void* who) +{ + release_object(proc, obj, who, NULL); +} + inline static status_t finish_flatten_binder( const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out) { @@ -504,7 +532,7 @@ status_t Parcel::appendFrom(const Parcel *parcel, size_t offset, size_t len) flat_binder_object* flat = reinterpret_cast<flat_binder_object*>(mData + off); - acquire_object(proc, *flat, this); + acquire_object(proc, *flat, this, &mOpenAshmemSize); if (flat->type == BINDER_TYPE_FD) { // If this is a file descriptor, we need to dup it so the @@ -923,8 +951,6 @@ status_t Parcel::writeBlob(size_t len, bool mutableCopy, 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; @@ -1026,7 +1052,7 @@ restart_write: // Need to write meta-data? if (nullMetaData || val.binder != 0) { mObjects[mObjectsSize] = mDataPos; - acquire_object(ProcessState::self(), val, this); + acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize); mObjectsSize++; } @@ -1609,7 +1635,7 @@ void Parcel::releaseObjects() i--; const flat_binder_object* flat = reinterpret_cast<flat_binder_object*>(data+objects[i]); - release_object(proc, *flat, this); + release_object(proc, *flat, this, &mOpenAshmemSize); } } @@ -1623,7 +1649,7 @@ void Parcel::acquireObjects() i--; const flat_binder_object* flat = reinterpret_cast<flat_binder_object*>(data+objects[i]); - acquire_object(proc, *flat, this); + acquire_object(proc, *flat, this, &mOpenAshmemSize); } } @@ -1805,7 +1831,7 @@ status_t Parcel::continueWrite(size_t desired) // will need to rescan because we may have lopped off the only FDs mFdsKnown = false; } - release_object(proc, *flat, this); + release_object(proc, *flat, this, &mOpenAshmemSize); } binder_size_t* objects = (binder_size_t*)realloc(mObjects, objectsSize*sizeof(binder_size_t)); @@ -1890,7 +1916,7 @@ void Parcel::initState() mFdsKnown = true; mAllowFds = true; mOwner = NULL; - mBlobAshmemSize = 0; + mOpenAshmemSize = 0; } void Parcel::scanForFds() const @@ -1910,7 +1936,15 @@ void Parcel::scanForFds() const size_t Parcel::getBlobAshmemSize() const { - return mBlobAshmemSize; + // This used to return the size of all blobs that were written to ashmem, now we're returning + // the ashmem currently referenced by this Parcel, which should be equivalent. + // TODO: Remove method once ABI can be changed. + return mOpenAshmemSize; +} + +size_t Parcel::getOpenAshmemSize() const +{ + return mOpenAshmemSize; } // --- Parcel::Blob --- diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp index d7a7885..8bdbc22 100644 --- a/libs/gui/IGraphicBufferProducer.cpp +++ b/libs/gui/IGraphicBufferProducer.cpp @@ -348,7 +348,7 @@ status_t BnGraphicBufferProducer::onTransact( uint32_t height = data.readUint32(); PixelFormat format = static_cast<PixelFormat>(data.readInt32()); uint32_t usage = data.readUint32(); - int buf; + int buf = 0; sp<Fence> fence; int result = dequeueBuffer(&buf, &fence, async, width, height, format, usage); @@ -389,7 +389,7 @@ status_t BnGraphicBufferProducer::onTransact( CHECK_INTERFACE(IGraphicBufferProducer, data, reply); sp<GraphicBuffer> buffer = new GraphicBuffer(); data.read(*buffer.get()); - int slot; + int slot = 0; int result = attachBuffer(&slot, buffer); reply->writeInt32(slot); reply->writeInt32(result); @@ -416,7 +416,7 @@ status_t BnGraphicBufferProducer::onTransact( } case QUERY: { CHECK_INTERFACE(IGraphicBufferProducer, data, reply); - int value; + int value = 0; int what = data.readInt32(); int res = query(what, &value); reply->writeInt32(value); diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp index 2545eec..235cbbd 100644 --- a/libs/gui/Sensor.cpp +++ b/libs/gui/Sensor.cpp @@ -223,6 +223,10 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion) } if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->requiredPermission) { mRequiredPermission = hwSensor->requiredPermission; + if (!strcmp(mRequiredPermission, SENSOR_PERMISSION_BODY_SENSORS)) { + AppOpsManager appOps; + mRequiredAppOp = appOps.permissionToOpCode(String16(SENSOR_PERMISSION_BODY_SENSORS)); + } } if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) { @@ -241,6 +245,11 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion) break; } + // Set DATA_INJECTION flag here. Defined in HAL 1_4. + if (halVersion >= SENSORS_DEVICE_API_VERSION_1_4) { + mFlags |= (hwSensor->flags & DATA_INJECTION_MASK); + } + // For the newer HALs log errors if reporting mask flags are set incorrectly. if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) { // Wake-up flag is set here. diff --git a/libs/input/Input.cpp b/libs/input/Input.cpp index 2c1418e..b64cb2c 100644 --- a/libs/input/Input.cpp +++ b/libs/input/Input.cpp @@ -424,7 +424,8 @@ void MotionEvent::transform(const float matrix[9]) { status_t MotionEvent::readFromParcel(Parcel* parcel) { size_t pointerCount = parcel->readInt32(); size_t sampleCount = parcel->readInt32(); - if (pointerCount == 0 || pointerCount > MAX_POINTERS || sampleCount == 0) { + if (pointerCount == 0 || pointerCount > MAX_POINTERS || + sampleCount == 0 || sampleCount > MAX_SAMPLES) { return BAD_VALUE; } diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp index 0382f57..7f83da5 100644 --- a/libs/input/InputTransport.cpp +++ b/libs/input/InputTransport.cpp @@ -51,6 +51,10 @@ static const nsecs_t RESAMPLE_LATENCY = 5 * NANOS_PER_MS; // Minimum time difference between consecutive samples before attempting to resample. static const nsecs_t RESAMPLE_MIN_DELTA = 2 * NANOS_PER_MS; +// Maximum time difference between consecutive samples before attempting to resample +// by extrapolation. +static const nsecs_t RESAMPLE_MAX_DELTA = 20 * NANOS_PER_MS; + // Maximum time to predict forward from the last known state, to avoid predicting too // far into the future. This time is further bounded by 50% of the last time delta. static const nsecs_t RESAMPLE_MAX_PREDICTION = 8 * NANOS_PER_MS; @@ -724,7 +728,7 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, nsecs_t delta = future.eventTime - current->eventTime; if (delta < RESAMPLE_MIN_DELTA) { #if DEBUG_RESAMPLING - ALOGD("Not resampled, delta time is %lld ns.", delta); + ALOGD("Not resampled, delta time is too small: %lld ns.", delta); #endif return; } @@ -736,7 +740,12 @@ void InputConsumer::resampleTouchState(nsecs_t sampleTime, MotionEvent* event, nsecs_t delta = current->eventTime - other->eventTime; if (delta < RESAMPLE_MIN_DELTA) { #if DEBUG_RESAMPLING - ALOGD("Not resampled, delta time is %lld ns.", delta); + ALOGD("Not resampled, delta time is too small: %lld ns.", delta); +#endif + return; + } else if (delta > RESAMPLE_MAX_DELTA) { +#if DEBUG_RESAMPLING + ALOGD("Not resampled, delta time is too large: %lld ns.", delta); #endif return; } diff --git a/libs/input/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp index b03e01e..df3f0dd 100644 --- a/libs/input/KeyCharacterMap.cpp +++ b/libs/input/KeyCharacterMap.cpp @@ -332,33 +332,75 @@ status_t KeyCharacterMap::mapKey(int32_t scanCode, int32_t usageCode, int32_t* o if (usageCode) { ssize_t index = mKeysByUsageCode.indexOfKey(usageCode); if (index >= 0) { + *outKeyCode = mKeysByUsageCode.valueAt(index); #if DEBUG_MAPPING - ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", - scanCode, usageCode, *outKeyCode); + ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", + scanCode, usageCode, *outKeyCode); #endif - *outKeyCode = mKeysByUsageCode.valueAt(index); return OK; } } if (scanCode) { ssize_t index = mKeysByScanCode.indexOfKey(scanCode); if (index >= 0) { + *outKeyCode = mKeysByScanCode.valueAt(index); #if DEBUG_MAPPING - ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", - scanCode, usageCode, *outKeyCode); + ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.", + scanCode, usageCode, *outKeyCode); #endif - *outKeyCode = mKeysByScanCode.valueAt(index); return OK; } } #if DEBUG_MAPPING - ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode); + ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Failed.", scanCode, usageCode); #endif *outKeyCode = AKEYCODE_UNKNOWN; return NAME_NOT_FOUND; } +void KeyCharacterMap::tryRemapKey(int32_t keyCode, int32_t metaState, + int32_t *outKeyCode, int32_t *outMetaState) const { + *outKeyCode = keyCode; + *outMetaState = metaState; + + const Key* key; + const Behavior* behavior; + if (getKeyBehavior(keyCode, metaState, &key, &behavior)) { + if (behavior->replacementKeyCode) { + *outKeyCode = behavior->replacementKeyCode; + int32_t newMetaState = metaState & ~behavior->metaState; + // Reset dependent meta states. + if (behavior->metaState & AMETA_ALT_ON) { + newMetaState &= ~(AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON); + } + if (behavior->metaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) { + newMetaState &= ~AMETA_ALT_ON; + } + if (behavior->metaState & AMETA_CTRL_ON) { + newMetaState &= ~(AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON); + } + if (behavior->metaState & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) { + newMetaState &= ~AMETA_CTRL_ON; + } + if (behavior->metaState & AMETA_SHIFT_ON) { + newMetaState &= ~(AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON); + } + if (behavior->metaState & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) { + newMetaState &= ~AMETA_SHIFT_ON; + } + // ... and put universal bits back if needed + *outMetaState = normalizeMetaState(newMetaState); + } + } + +#if DEBUG_MAPPING + ALOGD("tryRemapKey: keyCode=%d, metaState=0x%08x ~ " + "replacement keyCode=%d, replacement metaState=0x%08x.", + keyCode, metaState, *outKeyCode, *outMetaState); +#endif +} + bool KeyCharacterMap::getKey(int32_t keyCode, const Key** outKey) const { ssize_t index = mKeys.indexOfKey(keyCode); if (index >= 0) { @@ -584,6 +626,7 @@ sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) { int32_t metaState = parcel->readInt32(); char16_t character = parcel->readInt32(); int32_t fallbackKeyCode = parcel->readInt32(); + int32_t replacementKeyCode = parcel->readInt32(); if (parcel->errorCheck()) { return NULL; } @@ -592,6 +635,7 @@ sp<KeyCharacterMap> KeyCharacterMap::readFromParcel(Parcel* parcel) { behavior->metaState = metaState; behavior->character = character; behavior->fallbackKeyCode = fallbackKeyCode; + behavior->replacementKeyCode = replacementKeyCode; if (lastBehavior) { lastBehavior->next = behavior; } else { @@ -624,6 +668,7 @@ void KeyCharacterMap::writeToParcel(Parcel* parcel) const { parcel->writeInt32(behavior->metaState); parcel->writeInt32(behavior->character); parcel->writeInt32(behavior->fallbackKeyCode); + parcel->writeInt32(behavior->replacementKeyCode); } parcel->writeInt32(0); } @@ -655,13 +700,14 @@ KeyCharacterMap::Key::~Key() { // --- KeyCharacterMap::Behavior --- KeyCharacterMap::Behavior::Behavior() : - next(NULL), metaState(0), character(0), fallbackKeyCode(0) { + next(NULL), metaState(0), character(0), fallbackKeyCode(0), replacementKeyCode(0) { } KeyCharacterMap::Behavior::Behavior(const Behavior& other) : next(other.next ? new Behavior(*other.next) : NULL), metaState(other.metaState), character(other.character), - fallbackKeyCode(other.fallbackKeyCode) { + fallbackKeyCode(other.fallbackKeyCode), + replacementKeyCode(other.replacementKeyCode) { } @@ -923,6 +969,7 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { Behavior behavior; bool haveCharacter = false; bool haveFallback = false; + bool haveReplacement = false; do { char ch = mTokenizer->peekChar(); @@ -939,6 +986,11 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { mTokenizer->getLocation().string()); return BAD_VALUE; } + if (haveReplacement) { + ALOGE("%s: Cannot combine character literal with replace action.", + mTokenizer->getLocation().string()); + return BAD_VALUE; + } behavior.character = character; haveCharacter = true; } else { @@ -949,6 +1001,11 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { mTokenizer->getLocation().string()); return BAD_VALUE; } + if (haveReplacement) { + ALOGE("%s: Cannot combine 'none' with replace action.", + mTokenizer->getLocation().string()); + return BAD_VALUE; + } haveCharacter = true; } else if (token == "fallback") { mTokenizer->skipDelimiters(WHITESPACE); @@ -960,13 +1017,36 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { token.string()); return BAD_VALUE; } - if (haveFallback) { - ALOGE("%s: Cannot combine multiple fallback key codes.", + if (haveFallback || haveReplacement) { + ALOGE("%s: Cannot combine multiple fallback/replacement key codes.", mTokenizer->getLocation().string()); return BAD_VALUE; } behavior.fallbackKeyCode = keyCode; haveFallback = true; + } else if (token == "replace") { + mTokenizer->skipDelimiters(WHITESPACE); + token = mTokenizer->nextToken(WHITESPACE); + int32_t keyCode = getKeyCodeByLabel(token.string()); + if (!keyCode) { + ALOGE("%s: Invalid key code label for replace, got '%s'.", + mTokenizer->getLocation().string(), + token.string()); + return BAD_VALUE; + } + if (haveCharacter) { + ALOGE("%s: Cannot combine character literal with replace action.", + mTokenizer->getLocation().string()); + return BAD_VALUE; + } + if (haveFallback || haveReplacement) { + ALOGE("%s: Cannot combine multiple fallback/replacement key codes.", + mTokenizer->getLocation().string()); + return BAD_VALUE; + } + behavior.replacementKeyCode = keyCode; + haveReplacement = true; + } else { ALOGE("%s: Expected a key behavior after ':'.", mTokenizer->getLocation().string()); @@ -1016,8 +1096,10 @@ status_t KeyCharacterMap::Parser::parseKeyProperty() { newBehavior->next = key->firstBehavior; key->firstBehavior = newBehavior; #if DEBUG_PARSER - ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d.", mKeyCode, - newBehavior->metaState, newBehavior->character, newBehavior->fallbackKeyCode); + ALOGD("Parsed key meta: keyCode=%d, meta=0x%x, char=%d, fallback=%d replace=%d.", + mKeyCode, + newBehavior->metaState, newBehavior->character, + newBehavior->fallbackKeyCode, newBehavior->replacementKeyCode); #endif break; } diff --git a/libs/input/Keyboard.cpp b/libs/input/Keyboard.cpp index f4d9507..9a01395 100644 --- a/libs/input/Keyboard.cpp +++ b/libs/input/Keyboard.cpp @@ -176,6 +176,11 @@ static int32_t setEphemeralMetaState(int32_t mask, bool down, int32_t oldMetaSta ~(mask | AMETA_ALT_ON | AMETA_SHIFT_ON | AMETA_CTRL_ON | AMETA_META_ON); } + return normalizeMetaState(newMetaState); +} + +int32_t normalizeMetaState(int32_t oldMetaState) { + int32_t newMetaState = oldMetaState; if (newMetaState & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) { newMetaState |= AMETA_ALT_ON; } diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 8378907..cdec565 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -595,15 +595,6 @@ EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) return setError(EGL_BAD_SURFACE, EGL_FALSE); egl_surface_t * const s = get_surface(surface); - ANativeWindow* window = s->win.get(); - if (window) { - int result = native_window_api_disconnect(window, NATIVE_WINDOW_API_EGL); - if (result != OK) { - ALOGE("eglDestroySurface: native_window_api_disconnect (win=%p) " - "failed (%#x)", - window, result); - } - } EGLBoolean result = s->cnx->egl.eglDestroySurface(dp->disp.dpy, s->surface); if (result == EGL_TRUE) { _s.terminate(); diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp index 98cfe2b..2a53dec 100644 --- a/services/inputflinger/EventHub.cpp +++ b/services/inputflinger/EventHub.cpp @@ -438,10 +438,12 @@ bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, return false; } -status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, - int32_t* outKeycode, uint32_t* outFlags) const { +status_t EventHub::mapKey(int32_t deviceId, + int32_t scanCode, int32_t usageCode, int32_t metaState, + int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const { AutoMutex _l(mLock); Device* device = getDeviceLocked(deviceId); + status_t status = NAME_NOT_FOUND; if (device) { // Check the key character map first. @@ -449,22 +451,34 @@ status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, if (kcm != NULL) { if (!kcm->mapKey(scanCode, usageCode, outKeycode)) { *outFlags = 0; - return NO_ERROR; + status = NO_ERROR; } } // Check the key layout next. - if (device->keyMap.haveKeyLayout()) { + if (status != NO_ERROR && device->keyMap.haveKeyLayout()) { if (!device->keyMap.keyLayoutMap->mapKey( scanCode, usageCode, outKeycode, outFlags)) { - return NO_ERROR; + status = NO_ERROR; + } + } + + if (status == NO_ERROR) { + if (kcm != NULL) { + kcm->tryRemapKey(*outKeycode, metaState, outKeycode, outMetaState); + } else { + *outMetaState = metaState; } } } - *outKeycode = 0; - *outFlags = 0; - return NAME_NOT_FOUND; + if (status != NO_ERROR) { + *outKeycode = 0; + *outFlags = 0; + *outMetaState = metaState; + } + + return status; } status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const { diff --git a/services/inputflinger/EventHub.h b/services/inputflinger/EventHub.h index 7c3e11e..6869253 100644 --- a/services/inputflinger/EventHub.h +++ b/services/inputflinger/EventHub.h @@ -200,8 +200,9 @@ public: virtual bool hasInputProperty(int32_t deviceId, int property) const = 0; - virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, - int32_t* outKeycode, uint32_t* outFlags) const = 0; + virtual status_t mapKey(int32_t deviceId, + int32_t scanCode, int32_t usageCode, int32_t metaState, + int32_t* outKeycode, int32_t *outMetaState, uint32_t* outFlags) const = 0; virtual status_t mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const = 0; @@ -288,8 +289,9 @@ public: virtual bool hasInputProperty(int32_t deviceId, int property) const; - virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, - int32_t* outKeycode, uint32_t* outFlags) const; + virtual status_t mapKey(int32_t deviceId, + int32_t scanCode, int32_t usageCode, int32_t metaState, + int32_t* outKeycode, int32_t *outMetaState, uint32_t* outFlags) const; virtual status_t mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const; diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp index d7329d9..3ba38b5 100644 --- a/services/inputflinger/InputReader.cpp +++ b/services/inputflinger/InputReader.cpp @@ -2182,13 +2182,7 @@ void KeyboardInputMapper::process(const RawEvent* rawEvent) { mCurrentHidUsage = 0; if (isKeyboardOrGamepadKey(scanCode)) { - int32_t keyCode; - uint32_t flags; - if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) { - keyCode = AKEYCODE_UNKNOWN; - flags = 0; - } - processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags); + processKey(rawEvent->when, rawEvent->value != 0, scanCode, usageCode); } break; } @@ -2213,8 +2207,18 @@ bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) { || (scanCode >= BTN_JOYSTICK && scanCode < BTN_DIGI); } -void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, - int32_t scanCode, uint32_t policyFlags) { +void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t scanCode, + int32_t usageCode) { + int32_t keyCode; + int32_t keyMetaState; + uint32_t policyFlags; + + if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, mMetaState, + &keyCode, &keyMetaState, &policyFlags)) { + keyCode = AKEYCODE_UNKNOWN; + keyMetaState = mMetaState; + policyFlags = 0; + } if (down) { // Rotate key codes according to orientation if needed. @@ -2267,6 +2271,12 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, if (metaStateChanged) { mMetaState = newMetaState; updateLedState(false); + + // If global meta state changed send it along with the key. + // If it has not changed then we'll use what keymap gave us, + // since key replacement logic might temporarily reset a few + // meta bits for given key. + keyMetaState = newMetaState; } nsecs_t downTime = mDownTime; @@ -2294,7 +2304,7 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode, NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags, down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP, - AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime); + AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime); getListener()->notifyKey(&args); } @@ -3634,8 +3644,10 @@ void TouchInputMapper::configureVirtualKeys() { virtualKey.scanCode = virtualKeyDefinition.scanCode; int32_t keyCode; + int32_t dummyKeyMetaState; uint32_t flags; - if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) { + if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, 0, + &keyCode, &dummyKeyMetaState, &flags)) { ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode); mVirtualKeys.pop(); // drop the key diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h index 58db3dc..3e931fe 100644 --- a/services/inputflinger/InputReader.h +++ b/services/inputflinger/InputReader.h @@ -1154,8 +1154,7 @@ private: bool isKeyboardOrGamepadKey(int32_t scanCode); - void processKey(nsecs_t when, bool down, int32_t keyCode, int32_t scanCode, - uint32_t policyFlags); + void processKey(nsecs_t when, bool down, int32_t scanCode, int32_t usageCode); ssize_t findKeyDown(int32_t scanCode); diff --git a/services/inputflinger/host/InputDriver.cpp b/services/inputflinger/host/InputDriver.cpp index cb4ccbe..630a596 100644 --- a/services/inputflinger/host/InputDriver.cpp +++ b/services/inputflinger/host/InputDriver.cpp @@ -14,11 +14,8 @@ * limitations under the License. */ -#include <functional> #include <stdint.h> #include <sys/types.h> -#include <unordered_map> -#include <vector> #define LOG_TAG "InputDriver" @@ -28,9 +25,7 @@ #include "InputHost.h" #include <hardware/input.h> -#include <input/InputDevice.h> #include <utils/Log.h> -#include <utils/PropertyMap.h> #include <utils/String8.h> #define INDENT2 " " @@ -42,7 +37,6 @@ static input_host_callbacks_t kCallbacks = { .create_device_definition = create_device_definition, .create_input_report_definition = create_input_report_definition, .create_output_report_definition = create_output_report_definition, - .free_report_definition = free_report_definition, .input_device_definition_add_report = input_device_definition_add_report, .input_report_definition_add_collection = input_report_definition_add_collection, .input_report_definition_declare_usage_int = input_report_definition_declare_usage_int, @@ -75,214 +69,78 @@ void InputDriver::dump(String8& result) { result.appendFormat(INDENT2 "HAL Input Driver (%s)\n", mName.string()); } -} // namespace android - -struct input_property_map { - android::PropertyMap* propertyMap; -}; - -struct input_property { - android::String8 key; - android::String8 value; -}; - -struct input_device_identifier { - const char* name; - const char* uniqueId; - input_bus_t bus; - int32_t vendorId; - int32_t productId; - int32_t version; -}; - -struct input_device_definition { - std::vector<input_report_definition*> reportDefs; -}; - -struct input_device_handle { - input_device_identifier_t* id; - input_device_definition_t* def; -}; - -struct input_int_usage { - input_usage_t usage; - int32_t min; - int32_t max; - float resolution; -}; - -struct input_collection { - int32_t arity; - std::vector<input_int_usage> intUsages; - std::vector<input_usage_t> boolUsages; -}; - -struct InputCollectionIdHasher { - std::size_t operator()(const input_collection_id& id) const { - return std::hash<int>()(static_cast<int>(id)); - } -}; - -struct input_report_definition { - std::unordered_map<input_collection_id_t, input_collection, InputCollectionIdHasher> collections; -}; // HAL wrapper functions -namespace android { - -::input_device_identifier_t* create_device_identifier(input_host_t* host, +input_device_identifier_t* create_device_identifier(input_host_t* host, const char* name, int32_t product_id, int32_t vendor_id, input_bus_t bus, const char* unique_id) { - auto identifier = new ::input_device_identifier { - .name = name, - .productId = product_id, - .vendorId = vendor_id, - //.bus = bus, - .uniqueId = unique_id, - }; - // store this identifier somewhere? in the host? - return identifier; + return nullptr; } input_device_definition_t* create_device_definition(input_host_t* host) { - return new ::input_device_definition; + return nullptr; } input_report_definition_t* create_input_report_definition(input_host_t* host) { - return new ::input_report_definition; + return nullptr; } input_report_definition_t* create_output_report_definition(input_host_t* host) { - return new ::input_report_definition; -} - -void free_report_definition(input_host_t* host, input_report_definition_t* report_def) { - delete report_def; + return nullptr; } void input_device_definition_add_report(input_host_t* host, - input_device_definition_t* d, input_report_definition_t* r) { - d->reportDefs.push_back(r); -} + input_device_definition_t* d, input_report_definition_t* r) { } void input_report_definition_add_collection(input_host_t* host, - input_report_definition_t* report, input_collection_id_t id, int32_t arity) { - report->collections[id] = {.arity = arity}; -} + input_report_definition_t* report, input_collection_id_t id, int32_t arity) { } void input_report_definition_declare_usage_int(input_host_t* host, input_report_definition_t* report, input_collection_id_t id, - input_usage_t usage, int32_t min, int32_t max, float resolution) { - if (report->collections.find(id) != report->collections.end()) { - report->collections[id].intUsages.push_back({ - .usage = usage, .min = min, .max = max, .resolution = resolution}); - } -} + input_usage_t usage, int32_t min, int32_t max, float resolution) { } void input_report_definition_declare_usages_bool(input_host_t* host, input_report_definition_t* report, input_collection_id_t id, - input_usage_t* usage, size_t usage_count) { - if (report->collections.find(id) != report->collections.end()) { - for (size_t i = 0; i < usage_count; ++i) { - report->collections[id].boolUsages.push_back(usage[i]); - } - } -} + input_usage_t* usage, size_t usage_count) { } + input_device_handle_t* register_device(input_host_t* host, input_device_identifier_t* id, input_device_definition_t* d) { - ALOGD("Registering device %s with %d input reports", id->name, d->reportDefs.size()); - return new input_device_handle{ .id = id, .def = d }; + return nullptr; } input_report_t* input_allocate_report(input_host_t* host, input_report_definition_t* r) { - ALOGD("Allocating input report for definition %p", r); return nullptr; } - void input_report_set_usage_int(input_host_t* host, input_report_t* r, input_collection_id_t id, input_usage_t usage, int32_t value, int32_t arity_index) { } void input_report_set_usage_bool(input_host_t* host, input_report_t* r, input_collection_id_t id, input_usage_t usage, bool value, int32_t arity_index) { } -void report_event(input_host_t* host, input_device_handle_t* d, input_report_t* report) { - ALOGD("report_event %p for handle %p", report, d); -} +void report_event(input_host_t* host, input_device_handle_t* d, input_report_t* report) { } input_property_map_t* input_get_device_property_map(input_host_t* host, input_device_identifier_t* id) { - InputDeviceIdentifier idi; - idi.name = id->name; - idi.uniqueId = id->uniqueId; - idi.bus = id->bus; - idi.vendor = id->vendorId; - idi.product = id->productId; - idi.version = id->version; - - String8 configFile = getInputDeviceConfigurationFilePathByDeviceIdentifier( - idi, INPUT_DEVICE_CONFIGURATION_FILE_TYPE_CONFIGURATION); - if (configFile.isEmpty()) { - ALOGD("No input device configuration file found for device '%s'.", - idi.name.string()); - } else { - auto propMap = new input_property_map_t(); - status_t status = PropertyMap::load(configFile, &propMap->propertyMap); - if (status) { - ALOGE("Error loading input device configuration file for device '%s'. " - "Using default configuration.", - idi.name.string()); - delete propMap; - return nullptr; - } - return propMap; - } return nullptr; } input_property_t* input_get_device_property(input_host_t* host, input_property_map_t* map, const char* key) { - String8 keyString(key); - if (map != nullptr) { - if (map->propertyMap->hasProperty(keyString)) { - auto prop = new input_property_t(); - if (!map->propertyMap->tryGetProperty(keyString, prop->value)) { - delete prop; - return nullptr; - } - prop->key = keyString; - return prop; - } - } return nullptr; } const char* input_get_property_key(input_host_t* host, input_property_t* property) { - if (property != nullptr) { - return property->key.string(); - } return nullptr; } const char* input_get_property_value(input_host_t* host, input_property_t* property) { - if (property != nullptr) { - return property->value.string(); - } return nullptr; } -void input_free_device_property(input_host_t* host, input_property_t* property) { - if (property != nullptr) { - delete property; - } -} +void input_free_device_property(input_host_t* host, input_property_t* property) { } -void input_free_device_property_map(input_host_t* host, input_property_map_t* map) { - if (map != nullptr) { - delete map->propertyMap; - delete map; - } -} +void input_free_device_property_map(input_host_t* host, input_property_map_t* map) { } } // namespace android diff --git a/services/inputflinger/host/InputDriver.h b/services/inputflinger/host/InputDriver.h index 9bc14a7..7734ac2 100644 --- a/services/inputflinger/host/InputDriver.h +++ b/services/inputflinger/host/InputDriver.h @@ -68,8 +68,6 @@ input_report_definition_t* create_input_report_definition(input_host_t* host); input_report_definition_t* create_output_report_definition(input_host_t* host); -void free_report_definition(input_host_t* host, input_report_definition_t* report_def); - void input_device_definition_add_report(input_host_t* host, input_device_definition_t* d, input_report_definition_t* r); diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index f34b810..42bc865 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -518,8 +518,9 @@ private: return false; } - virtual status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, - int32_t* outKeycode, uint32_t* outFlags) const { + virtual status_t mapKey(int32_t deviceId, + int32_t scanCode, int32_t usageCode, int32_t metaState, + int32_t* outKeycode, int32_t *outMetaState, uint32_t* outFlags) const { Device* device = getDevice(deviceId); if (device) { const KeyInfo* key = getKey(device, scanCode, usageCode); @@ -530,6 +531,9 @@ private: if (outFlags) { *outFlags = key->flags; } + if (outMetaState) { + *outMetaState = metaState; + } return OK; } } diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp index 40b21a9..fd72b23 100644 --- a/services/sensorservice/SensorService.cpp +++ b/services/sensorservice/SensorService.cpp @@ -912,10 +912,15 @@ status_t SensorService::enable(const sp<SensorEventConnection>& connection, status_t err = sensor->batch(connection.get(), handle, 0, samplingPeriodNs, maxBatchReportLatencyNs); - // Call flush() before calling activate() on the sensor. Wait for a first flush complete - // event before sending events on this connection. Ignore one-shot sensors which don't - // support flush(). Also if this sensor isn't already active, don't call flush(). - if (err == NO_ERROR && sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT && + // Call flush() before calling activate() on the sensor. Wait for a first + // flush complete event before sending events on this connection. Ignore + // one-shot sensors which don't support flush(). Ignore on-change sensors + // to maintain the on-change logic (any on-change events except the initial + // one should be trigger by a change in value). Also if this sensor isn't + // already active, don't call flush(). + if (err == NO_ERROR && + sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT && + sensor->getSensor().getReportingMode() != AREPORTING_MODE_ON_CHANGE && rec->getNumConnections() > 1) { connection->setFirstFlushPending(handle, true); status_t err_flush = sensor->flush(connection.get(), handle); diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp index 2dad005..0859149 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp +++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp @@ -336,10 +336,20 @@ static const uint32_t DISPLAY_ATTRIBUTES[] = { HWC_DISPLAY_HEIGHT, HWC_DISPLAY_DPI_X, HWC_DISPLAY_DPI_Y, + HWC_DISPLAY_COLOR_TRANSFORM, HWC_DISPLAY_NO_ATTRIBUTE, }; #define NUM_DISPLAY_ATTRIBUTES (sizeof(DISPLAY_ATTRIBUTES) / sizeof(DISPLAY_ATTRIBUTES)[0]) +static const uint32_t PRE_HWC15_DISPLAY_ATTRIBUTES[] = { + HWC_DISPLAY_VSYNC_PERIOD, + HWC_DISPLAY_WIDTH, + HWC_DISPLAY_HEIGHT, + HWC_DISPLAY_DPI_X, + HWC_DISPLAY_DPI_Y, + HWC_DISPLAY_NO_ATTRIBUTE, +}; + status_t HWComposer::queryDisplayProperties(int disp) { LOG_ALWAYS_FATAL_IF(!mHwc || !hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_1)); @@ -362,6 +372,12 @@ status_t HWComposer::queryDisplayProperties(int disp) { for (size_t c = 0; c < numConfigs; ++c) { err = mHwc->getDisplayAttributes(mHwc, disp, configs[c], DISPLAY_ATTRIBUTES, values); + // If this is a pre-1.5 HWC, it may not know about color transform, so + // try again with a smaller set of attributes + if (err != NO_ERROR) { + err = mHwc->getDisplayAttributes(mHwc, disp, configs[c], + PRE_HWC15_DISPLAY_ATTRIBUTES, values); + } if (err != NO_ERROR) { // we can't get this display's info. turn it off. mDisplayData[disp].connected = false; @@ -386,6 +402,9 @@ status_t HWComposer::queryDisplayProperties(int disp) { case HWC_DISPLAY_DPI_Y: config.ydpi = values[i] / 1000.0f; break; + case HWC_DISPLAY_COLOR_TRANSFORM: + config.colorTransform = values[i]; + break; default: ALOG_ASSERT(false, "unknown display attribute[%zu] %#x", i, DISPLAY_ATTRIBUTES[i]); @@ -1162,9 +1181,11 @@ void HWComposer::dump(String8& result) const { result.appendFormat(" Display[%zd] configurations (* current):\n", i); for (size_t c = 0; c < disp.configs.size(); ++c) { const DisplayConfig& config(disp.configs[c]); - result.appendFormat(" %s%zd: %ux%u, xdpi=%f, ydpi=%f, refresh=%" PRId64 "\n", - c == disp.currentConfig ? "* " : "", c, config.width, config.height, - config.xdpi, config.ydpi, config.refresh); + result.appendFormat(" %s%zd: %ux%u, xdpi=%f, ydpi=%f" + ", refresh=%" PRId64 ", colorTransform=%d\n", + c == disp.currentConfig ? "* " : "", c, + config.width, config.height, config.xdpi, config.ydpi, + config.refresh, config.colorTransform); } if (disp.list) { diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h index cc98b4c..5e0b3d8 100644 --- a/services/surfaceflinger/DisplayHardware/HWComposer.h +++ b/services/surfaceflinger/DisplayHardware/HWComposer.h @@ -257,6 +257,7 @@ public: float xdpi; float ydpi; nsecs_t refresh; + int colorTransform; }; // Query display parameters. Pass in a display index (e.g. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 01ffac2..fdc3650 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -632,6 +632,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display, info.ydpi = ydpi; info.fps = float(1e9 / hwConfig.refresh); info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS; + info.colorTransform = hwConfig.colorTransform; // This is how far in advance a buffer must be queued for // presentation at a given time. If you want a buffer to appear |