Merge "atrace: add database tag"
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 698ffb1..81c8967 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -26,6 +26,7 @@
#include <string.h>
#include <sys/sendfile.h>
#include <time.h>
+#include <unistd.h>
#include <zlib.h>
#include <binder/IBinder.h>
@@ -212,6 +213,9 @@
static const char* k_tracePath =
"/sys/kernel/debug/tracing/trace";
+static const char* k_traceStreamPath =
+ "/sys/kernel/debug/tracing/trace_pipe";
+
static const char* k_traceMarkerPath =
"/sys/kernel/debug/tracing/trace_marker";
@@ -730,6 +734,31 @@
setTracingEnabled(false);
}
+// Read data from the tracing pipe and forward to stdout
+static void streamTrace()
+{
+ char trace_data[4096];
+ int traceFD = open(k_traceStreamPath, O_RDWR);
+ if (traceFD == -1) {
+ fprintf(stderr, "error opening %s: %s (%d)\n", k_traceStreamPath,
+ strerror(errno), errno);
+ return;
+ }
+ while (!g_traceAborted) {
+ ssize_t bytes_read = read(traceFD, trace_data, 4096);
+ if (bytes_read > 0) {
+ write(STDOUT_FILENO, trace_data, bytes_read);
+ fflush(stdout);
+ } else {
+ if (!g_traceAborted) {
+ fprintf(stderr, "read returned %zd bytes err %d (%s)\n",
+ bytes_read, errno, strerror(errno));
+ }
+ break;
+ }
+ }
+}
+
// Read the current kernel trace and write it to stdout.
static void dumpTrace()
{
@@ -876,6 +905,10 @@
" --async_dump dump the current contents of circular trace buffer\n"
" --async_stop stop tracing and dump the current contents of circular\n"
" trace buffer\n"
+ " --stream stream trace to stdout as it enters the trace buffer\n"
+ " Note: this can take significant CPU time, and is best\n"
+ " used for measuring things that are not affected by\n"
+ " CPU performance, like pagecache usage.\n"
" --list_categories\n"
" list the available tracing categories\n"
);
@@ -887,6 +920,7 @@
bool traceStart = true;
bool traceStop = true;
bool traceDump = true;
+ bool traceStream = false;
if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
showHelp(argv[0]);
@@ -901,6 +935,7 @@
{"async_stop", no_argument, 0, 0 },
{"async_dump", no_argument, 0, 0 },
{"list_categories", no_argument, 0, 0 },
+ {"stream", no_argument, 0, 0 },
{ 0, 0, 0, 0 }
};
@@ -967,6 +1002,9 @@
async = true;
traceStart = false;
traceStop = false;
+ } else if (!strcmp(long_options[option_index].name, "stream")) {
+ traceStream = true;
+ traceDump = false;
} else if (!strcmp(long_options[option_index].name, "list_categories")) {
listSupportedCategories();
exit(0);
@@ -992,8 +1030,10 @@
ok &= startTrace();
if (ok && traceStart) {
- printf("capturing trace...");
- fflush(stdout);
+ if (!traceStream) {
+ printf("capturing trace...");
+ fflush(stdout);
+ }
// We clear the trace after starting it because tracing gets enabled for
// each CPU individually in the kernel. Having the beginning of the trace
@@ -1003,7 +1043,7 @@
ok = clearTrace();
writeClockSyncMarker();
- if (ok && !async) {
+ if (ok && !async && !traceStream) {
// Sleep to allow the trace to be captured.
struct timespec timeLeft;
timeLeft.tv_sec = g_traceDurationSeconds;
@@ -1014,6 +1054,10 @@
}
} while (nanosleep(&timeLeft, &timeLeft) == -1 && errno == EINTR);
}
+
+ if (traceStream) {
+ streamTrace();
+ }
}
// Stop the trace and restore the default settings.
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index 81df92f..9d07b09 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -298,6 +298,7 @@
dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");
run_command("UPTIME", 10, "uptime", NULL);
dump_files("UPTIME MMC PERF", mmcblk0, skip_not_stat, dump_stat_from_fd);
+ dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd");
dump_file("MEMORY INFO", "/proc/meminfo");
run_command("CPU INFO", 10, "top", "-n", "1", "-d", "1", "-m", "30", "-H", NULL);
run_command("PROCRANK", 20, SU_PATH, "root", "procrank", NULL);
@@ -339,11 +340,12 @@
"-v", "printable",
"-d",
"*:v", NULL);
- timeout = logcat_timeout("events");
+ timeout = logcat_timeout("events") + logcat_timeout("security");
if (timeout < 20000) {
timeout = 20000;
}
run_command("EVENT LOG", timeout / 1000, "logcat", "-b", "events",
+ "-b", "security",
"-v", "threadtime",
"-v", "printable",
"-d",
@@ -360,8 +362,7 @@
run_command("LOG STATISTICS", 10, "logcat", "-b", "all", "-S", NULL);
- // raft disabled as per http://b/24159112
- // run_command("RAFT LOGS", 300, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL);
+ run_command("RAFT LOGS", 300, SU_PATH, "root", "logcompressor", "-r", RAFT_DIR, NULL);
/* show the traces we collected in main(), if that was done */
if (dump_traces_path != NULL) {
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index c5d3044..228f09c 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -84,4 +84,7 @@
/* Implemented by libdumpstate_board to dump board-specific info */
void dumpstate_board();
+/* dump eMMC Extended CSD data */
+void dump_emmc_ecsd(const char *ext_csd_path);
+
#endif /* _DUMPSTATE_H_ */
diff --git a/cmds/dumpstate/dumpstate.rc b/cmds/dumpstate/dumpstate.rc
index cd5d6c4..4cd1803 100644
--- a/cmds/dumpstate/dumpstate.rc
+++ b/cmds/dumpstate/dumpstate.rc
@@ -1,3 +1,8 @@
+on boot
+ # Allow bugreports access to eMMC 5.0 stats
+ chown root mount /sys/kernel/debug/mmc0/mmc0:0001/ext_csd
+ chmod 0440 /sys/kernel/debug/mmc0/mmc0:0001/ext_csd
+
service dumpstate /system/bin/dumpstate -s
class main
socket dumpstate stream 0660 shell log
diff --git a/cmds/dumpstate/utils.c b/cmds/dumpstate/utils.c
index 0dd0c21..47acb63 100644
--- a/cmds/dumpstate/utils.c
+++ b/cmds/dumpstate/utils.c
@@ -778,3 +778,120 @@
}
fclose(fp);
}
+
+void dump_emmc_ecsd(const char *ext_csd_path) {
+ static const size_t EXT_CSD_REV = 192;
+ static const size_t EXT_PRE_EOL_INFO = 267;
+ static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_A = 268;
+ static const size_t EXT_DEVICE_LIFE_TIME_EST_TYP_B = 269;
+ struct hex {
+ char str[2];
+ } buffer[512];
+ int fd, ext_csd_rev, ext_pre_eol_info;
+ ssize_t bytes_read;
+ static const char *ver_str[] = {
+ "4.0", "4.1", "4.2", "4.3", "Obsolete", "4.41", "4.5", "5.0"
+ };
+ static const char *eol_str[] = {
+ "Undefined",
+ "Normal",
+ "Warning (consumed 80% of reserve)",
+ "Urgent (consumed 90% of reserve)"
+ };
+
+ printf("------ %s Extended CSD ------\n", ext_csd_path);
+
+ fd = TEMP_FAILURE_RETRY(open(ext_csd_path,
+ O_RDONLY | O_NONBLOCK | O_CLOEXEC));
+ if (fd < 0) {
+ printf("*** %s: %s\n\n", ext_csd_path, strerror(errno));
+ return;
+ }
+
+ bytes_read = TEMP_FAILURE_RETRY(read(fd, buffer, sizeof(buffer)));
+ close(fd);
+ if (bytes_read < 0) {
+ printf("*** %s: %s\n\n", ext_csd_path, strerror(errno));
+ return;
+ }
+ if (bytes_read < (ssize_t)(EXT_CSD_REV * sizeof(struct hex))) {
+ printf("*** %s: truncated content %zd\n\n", ext_csd_path, bytes_read);
+ return;
+ }
+
+ ext_csd_rev = 0;
+ if (sscanf(buffer[EXT_CSD_REV].str, "%02x", &ext_csd_rev) != 1) {
+ printf("*** %s: EXT_CSD_REV parse error \"%.2s\"\n\n",
+ ext_csd_path, buffer[EXT_CSD_REV].str);
+ return;
+ }
+
+ printf("rev 1.%d (MMC %s)\n",
+ ext_csd_rev,
+ (ext_csd_rev < (int)(sizeof(ver_str) / sizeof(ver_str[0]))) ?
+ ver_str[ext_csd_rev] :
+ "Unknown");
+ if (ext_csd_rev < 7) {
+ printf("\n");
+ return;
+ }
+
+ if (bytes_read < (ssize_t)(EXT_PRE_EOL_INFO * sizeof(struct hex))) {
+ printf("*** %s: truncated content %zd\n\n", ext_csd_path, bytes_read);
+ return;
+ }
+
+ ext_pre_eol_info = 0;
+ if (sscanf(buffer[EXT_PRE_EOL_INFO].str, "%02x", &ext_pre_eol_info) != 1) {
+ printf("*** %s: PRE_EOL_INFO parse error \"%.2s\"\n\n",
+ ext_csd_path, buffer[EXT_PRE_EOL_INFO].str);
+ return;
+ }
+ printf("PRE_EOL_INFO %d (MMC %s)\n",
+ ext_pre_eol_info,
+ eol_str[(ext_pre_eol_info < (int)
+ (sizeof(eol_str) / sizeof(eol_str[0]))) ?
+ ext_pre_eol_info : 0]);
+
+ for (size_t lifetime = EXT_DEVICE_LIFE_TIME_EST_TYP_A;
+ lifetime <= EXT_DEVICE_LIFE_TIME_EST_TYP_B;
+ ++lifetime) {
+ int ext_device_life_time_est;
+ static const char *est_str[] = {
+ "Undefined",
+ "0-10% of device lifetime used",
+ "10-20% of device lifetime used",
+ "20-30% of device lifetime used",
+ "30-40% of device lifetime used",
+ "40-50% of device lifetime used",
+ "50-60% of device lifetime used",
+ "60-70% of device lifetime used",
+ "70-80% of device lifetime used",
+ "80-90% of device lifetime used",
+ "90-100% of device lifetime used",
+ "Exceeded the maximum estimated device lifetime",
+ };
+
+ if (bytes_read < (ssize_t)(lifetime * sizeof(struct hex))) {
+ printf("*** %s: truncated content %zd\n", ext_csd_path, bytes_read);
+ break;
+ }
+
+ ext_device_life_time_est = 0;
+ if (sscanf(buffer[lifetime].str, "%02x", &ext_device_life_time_est) != 1) {
+ printf("*** %s: DEVICE_LIFE_TIME_EST_TYP_%c parse error \"%.2s\"\n",
+ ext_csd_path,
+ (unsigned)(lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) + 'A',
+ buffer[lifetime].str);
+ continue;
+ }
+ printf("DEVICE_LIFE_TIME_EST_TYP_%c %d (MMC %s)\n",
+ (unsigned)(lifetime - EXT_DEVICE_LIFE_TIME_EST_TYP_A) + 'A',
+ ext_device_life_time_est,
+ est_str[(ext_device_life_time_est < (int)
+ (sizeof(est_str) / sizeof(est_str[0]))) ?
+ ext_device_life_time_est : 0]);
+ }
+
+ printf("\n");
+}
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 757290f..1b99582 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -16,8 +16,8 @@
#include "installd.h"
-#include <base/stringprintf.h>
-#include <base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/logging.h>
#include <cutils/sched_policy.h>
#include <diskusage/dirsize.h>
#include <logwrap/logwrap.h>
diff --git a/cmds/installd/installd.cpp b/cmds/installd/installd.cpp
index 7a16150..30e4f8b 100644
--- a/cmds/installd/installd.cpp
+++ b/cmds/installd/installd.cpp
@@ -16,7 +16,7 @@
#include "installd.h"
-#include <base/logging.h>
+#include <android-base/logging.h>
#include <sys/capability.h>
#include <sys/prctl.h>
diff --git a/cmds/installd/utils.cpp b/cmds/installd/utils.cpp
index abbd021..a98fec5 100644
--- a/cmds/installd/utils.cpp
+++ b/cmds/installd/utils.cpp
@@ -16,8 +16,8 @@
#include "installd.h"
-#include <base/stringprintf.h>
-#include <base/logging.h>
+#include <android-base/stringprintf.h>
+#include <android-base/logging.h>
#define CACHE_NOISY(x) //x
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index a12d68d..16a4790 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -20,6 +20,7 @@
#include <vector>
#include <cutils/native_handle.h>
+#include <nativehelper/ScopedFd.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/String16.h>
@@ -154,6 +155,17 @@
// will be closed once the parcel is destroyed.
status_t writeDupFileDescriptor(int fd);
+ // Place a file descriptor into the parcel. This will not affect the
+ // semantics of the smart file descriptor. A new descriptor will be
+ // created, and will be closed when the parcel is destroyed.
+ status_t writeUniqueFileDescriptor(
+ const ScopedFd& fd);
+
+ // Place a vector of file desciptors into the parcel. Each descriptor is
+ // dup'd as in writeDupFileDescriptor
+ status_t writeUniqueFileDescriptorVector(
+ const std::vector<ScopedFd>& val);
+
// Writes a blob to the parcel.
// If the blob is small, then it is stored in-place, otherwise it is
// transferred by way of an anonymous shared memory region. Prefer sending
@@ -250,6 +262,15 @@
// in the parcel, which you do not own -- use dup() to get your own copy.
int readFileDescriptor() const;
+ // Retrieve a smart file descriptor from the parcel.
+ status_t readUniqueFileDescriptor(
+ ScopedFd* val) const;
+
+
+ // Retrieve a vector of smart file descriptors from the parcel.
+ status_t readUniqueFileDescriptorVector(
+ std::vector<ScopedFd>* val) const;
+
// Reads a blob from the parcel.
// The caller should call release() on the blob after reading its contents.
status_t readBlob(size_t len, ReadableBlob* outBlob) const;
@@ -406,10 +427,12 @@
};
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/binder/Status.h b/include/binder/Status.h
index 04738f8..203a01e 100644
--- a/include/binder/Status.h
+++ b/include/binder/Status.h
@@ -60,31 +60,42 @@
EX_ILLEGAL_STATE = -5,
EX_NETWORK_MAIN_THREAD = -6,
EX_UNSUPPORTED_OPERATION = -7,
- EX_TRANSACTION_FAILED = -8,
+ EX_SERVICE_SPECIFIC = -8,
// This is special and Java specific; see Parcel.java.
EX_HAS_REPLY_HEADER = -128,
+ // This is special, and indicates to C++ binder proxies that the
+ // transaction has failed at a low level.
+ EX_TRANSACTION_FAILED = -129,
};
- // Allow authors to explicitly pick whether their integer is a status_t or
- // exception code.
- static Status fromExceptionCode(int32_t exception_code);
- static Status fromStatusT(status_t status);
// A more readable alias for the default constructor.
static Status ok();
+ // Authors should explicitly pick whether their integer is:
+ // - an exception code (EX_* above)
+ // - service specific error code
+ // - status_t
+ //
+ // Prefer a generic exception code when possible, then a service specific
+ // code, and finally a status_t for low level failures or legacy support.
+ // Exception codes and service specific errors map to nicer exceptions for
+ // Java clients.
+ static Status fromExceptionCode(int32_t exceptionCode);
+ static Status fromExceptionCode(int32_t exceptionCode,
+ const String8& message);
+ static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode);
+ static Status fromServiceSpecificError(int32_t serviceSpecificErrorCode,
+ const String8& message);
+ static Status fromStatusT(status_t status);
Status() = default;
- Status(int32_t exception_code, const String8& message);
- Status(int32_t exception_code, const char* message);
-
+ ~Status() = default;
// Status objects are copyable and contain just simple data.
Status(const Status& status) = default;
Status(Status&& status) = default;
Status& operator=(const Status& status) = default;
- ~Status() = default;
-
// Bear in mind that if the client or service is a Java endpoint, this
// is not the logic which will provide/interpret the data here.
status_t readFromParcel(const Parcel& parcel);
@@ -92,16 +103,22 @@
// Set one of the pre-defined exception types defined above.
void setException(int32_t ex, const String8& message);
- // A few of the status_t values map to exception codes, but most of them
- // simply map to "transaction failed."
+ // Set a service specific exception with error code.
+ void setServiceSpecificError(int32_t errorCode, const String8& message);
+ // Setting a |status| != OK causes generated code to return |status|
+ // from Binder transactions, rather than writing an exception into the
+ // reply Parcel. This is the least preferable way of reporting errors.
void setFromStatusT(status_t status);
// Get information about an exception.
- // Any argument may be given as nullptr.
- void getException(int32_t* returned_exception,
- String8* returned_message) const;
int32_t exceptionCode() const { return mException; }
const String8& exceptionMessage() const { return mMessage; }
+ status_t transactionError() const {
+ return mException == EX_TRANSACTION_FAILED ? mErrorCode : OK;
+ }
+ int32_t serviceSpecificErrorCode() const {
+ return mException == EX_SERVICE_SPECIFIC ? mErrorCode : 0;
+ }
bool isOk() const { return mException == EX_NONE; }
@@ -109,9 +126,18 @@
String8 toString8() const;
private:
- // We always write |mException| to the parcel.
- // If |mException| != EX_NONE, we write message as well.
+ Status(int32_t exceptionCode, int32_t errorCode);
+ Status(int32_t exceptionCode, int32_t errorCode, const String8& message);
+
+ // If |mException| == EX_TRANSACTION_FAILED, generated code will return
+ // |mErrorCode| as the result of the transaction rather than write an
+ // exception to the reply parcel.
+ //
+ // Otherwise, we always write |mException| to the parcel.
+ // If |mException| != EX_NONE, we write |mMessage| as well.
+ // If |mException| == EX_SERVICE_SPECIFIC we write |mErrorCode| as well.
int32_t mException = EX_NONE;
+ int32_t mErrorCode = 0;
String8 mMessage;
}; // class Status
diff --git a/include/input/Input.h b/include/input/Input.h
index 093219a..3b1c86b 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 @@
#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/KeyCharacterMap.h b/include/input/KeyCharacterMap.h
index 111139b..eb5840e 100644
--- a/include/input/KeyCharacterMap.h
+++ b/include/input/KeyCharacterMap.h
@@ -124,6 +124,11 @@
* 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;
+
#ifdef __ANDROID__
/* Reads a key map from a parcel. */
static sp<KeyCharacterMap> readFromParcel(Parcel* parcel);
@@ -151,6 +156,9 @@
/* 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 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/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 03348da..3abb44f 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -94,7 +94,7 @@
};
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:
@@ -121,8 +121,15 @@
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;
}
}
@@ -130,9 +137,15 @@
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) {
@@ -158,7 +171,16 @@
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;
}
}
@@ -166,6 +188,12 @@
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)
{
@@ -502,7 +530,7 @@
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
@@ -980,12 +1008,20 @@
return -errno;
}
status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
- if (err) {
+ if (err != OK) {
close(dupFd);
}
return err;
}
+status_t Parcel::writeUniqueFileDescriptor(const ScopedFd& fd) {
+ return writeDupFileDescriptor(fd.get());
+}
+
+status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<ScopedFd>& val) {
+ return writeTypedVector(val, &Parcel::writeUniqueFileDescriptor);
+}
+
status_t Parcel::writeBlob(size_t len, bool mutableCopy, WritableBlob* outBlob)
{
if (len > INT32_MAX) {
@@ -1011,8 +1047,6 @@
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;
@@ -1114,7 +1148,7 @@
// 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++;
}
@@ -1601,16 +1635,36 @@
int Parcel::readFileDescriptor() const
{
const flat_binder_object* flat = readObject(true);
- if (flat) {
- switch (flat->type) {
- case BINDER_TYPE_FD:
- //ALOGI("Returning file descriptor %ld from parcel %p", flat->handle, this);
- return flat->handle;
- }
+
+ if (flat && flat->type == BINDER_TYPE_FD) {
+ return flat->handle;
}
+
return BAD_TYPE;
}
+status_t Parcel::readUniqueFileDescriptor(ScopedFd* val) const
+{
+ int got = readFileDescriptor();
+
+ if (got == BAD_TYPE) {
+ return BAD_TYPE;
+ }
+
+ val->reset(dup(got));
+
+ if (val->get() < 0) {
+ return BAD_VALUE;
+ }
+
+ return OK;
+}
+
+
+status_t Parcel::readUniqueFileDescriptorVector(std::vector<ScopedFd>* val) const {
+ return readTypedVector(val, &Parcel::readUniqueFileDescriptor);
+}
+
status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
{
int32_t blobType;
@@ -1844,7 +1898,7 @@
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);
}
}
@@ -1858,7 +1912,7 @@
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);
}
}
@@ -1935,6 +1989,9 @@
pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
gParcelGlobalAllocSize += desired;
gParcelGlobalAllocSize -= mDataCapacity;
+ if (!mData) {
+ gParcelGlobalAllocCount++;
+ }
pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
mData = data;
mDataCapacity = desired;
@@ -2046,7 +2103,7 @@
// 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));
@@ -2066,7 +2123,6 @@
pthread_mutex_lock(&gParcelGlobalAllocSizeLock);
gParcelGlobalAllocSize += desired;
gParcelGlobalAllocSize -= mDataCapacity;
- gParcelGlobalAllocCount++;
pthread_mutex_unlock(&gParcelGlobalAllocSizeLock);
mData = data;
mDataCapacity = desired;
@@ -2132,7 +2188,7 @@
mFdsKnown = true;
mAllowFds = true;
mOwner = NULL;
- mBlobAshmemSize = 0;
+ mOpenAshmemSize = 0;
}
void Parcel::scanForFds() const
@@ -2152,7 +2208,15 @@
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/binder/Status.cpp b/libs/binder/Status.cpp
index 41fff3d..d3520d6 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -19,8 +19,26 @@
namespace android {
namespace binder {
-Status Status::fromExceptionCode(int32_t exception_code) {
- return Status(exception_code, "");
+Status Status::ok() {
+ return Status();
+}
+
+Status Status::fromExceptionCode(int32_t exceptionCode) {
+ return Status(exceptionCode, OK);
+}
+
+Status Status::fromExceptionCode(int32_t exceptionCode,
+ const String8& message) {
+ return Status(exceptionCode, OK, message);
+}
+
+Status Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode) {
+ return Status(EX_SERVICE_SPECIFIC, serviceSpecificErrorCode);
+}
+
+Status Status::fromServiceSpecificError(int32_t serviceSpecificErrorCode,
+ const String8& message) {
+ return Status(EX_SERVICE_SPECIFIC, serviceSpecificErrorCode, message);
}
Status Status::fromStatusT(status_t status) {
@@ -29,16 +47,13 @@
return ret;
}
-Status Status::ok() {
- return Status();
-}
+Status::Status(int32_t exceptionCode, int32_t errorCode)
+ : mException(exceptionCode),
+ mErrorCode(errorCode) {}
-Status::Status(int32_t exception_code, const String8& message)
- : mException(exception_code),
- mMessage(message) {}
-
-Status::Status(int32_t exception_code, const char* message)
- : mException(exception_code),
+Status::Status(int32_t exceptionCode, int32_t errorCode, const String8& message)
+ : mException(exceptionCode),
+ mErrorCode(errorCode),
mMessage(message) {}
status_t Status::readFromParcel(const Parcel& parcel) {
@@ -69,12 +84,32 @@
}
// The remote threw an exception. Get the message back.
- mMessage = String8(parcel.readString16());
+ String16 message;
+ status = parcel.readString16(&message);
+ if (status != OK) {
+ setFromStatusT(status);
+ return status;
+ }
+ mMessage = String8(message);
+
+ if (mException == EX_SERVICE_SPECIFIC) {
+ status = parcel.readInt32(&mErrorCode);
+ }
+ if (status != OK) {
+ setFromStatusT(status);
+ return status;
+ }
return status;
}
status_t Status::writeToParcel(Parcel* parcel) const {
+ // Something really bad has happened, and we're not going to even
+ // try returning rich error data.
+ if (mException == EX_TRANSACTION_FAILED) {
+ return mErrorCode;
+ }
+
status_t status = parcel->writeInt32(mException);
if (status != OK) { return status; }
if (mException == EX_NONE) {
@@ -82,39 +117,29 @@
return status;
}
status = parcel->writeString16(String16(mMessage));
- return status;
-}
-
-void Status::setFromStatusT(status_t status) {
- switch (status) {
- case NO_ERROR:
- mException = EX_NONE;
- mMessage.clear();
- break;
- case UNEXPECTED_NULL:
- mException = EX_NULL_POINTER;
- mMessage.setTo("Unexpected null reference in Parcel");
- break;
- default:
- mException = EX_TRANSACTION_FAILED;
- mMessage.setTo("Transaction failed");
- break;
+ if (mException != EX_SERVICE_SPECIFIC) {
+ // We have no more information to write.
+ return status;
}
+ status = parcel->writeInt32(mErrorCode);
+ return status;
}
void Status::setException(int32_t ex, const String8& message) {
mException = ex;
+ mErrorCode = NO_ERROR; // an exception, not a transaction failure.
mMessage.setTo(message);
}
-void Status::getException(int32_t* returned_exception,
- String8* returned_message) const {
- if (returned_exception) {
- *returned_exception = mException;
- }
- if (returned_message) {
- returned_message->setTo(mMessage);
- }
+void Status::setServiceSpecificError(int32_t errorCode, const String8& message) {
+ setException(EX_SERVICE_SPECIFIC, message);
+ mErrorCode = errorCode;
+}
+
+void Status::setFromStatusT(status_t status) {
+ mException = (status == NO_ERROR) ? EX_NONE : EX_TRANSACTION_FAILED;
+ mErrorCode = status;
+ mMessage.clear();
}
String8 Status::toString8() const {
@@ -123,6 +148,10 @@
ret.append("No error");
} else {
ret.appendFormat("Status(%d): '", mException);
+ if (mException == EX_SERVICE_SPECIFIC ||
+ mException == EX_TRANSACTION_FAILED) {
+ ret.appendFormat("%d: ", mErrorCode);
+ }
ret.append(String8(mMessage));
ret.append("'");
}
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 87e5b4d..a941e2d 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -696,15 +696,6 @@
mCore->validateConsistencyLocked();
} // Autolock scope
- // Wait without lock held
- if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
- // Waiting here allows for two full buffers to be queued but not a
- // third. In the event that frames take varying time, this makes a
- // small trade-off in favor of latency rather than throughput.
- mLastQueueBufferFence->waitForever("Throttling EGL Production");
- mLastQueueBufferFence = fence;
- }
-
// Don't send the GraphicBuffer through the callback, and don't send
// the slot number, since the consumer shouldn't need it
item.mGraphicBuffer.clear();
@@ -728,6 +719,15 @@
mCallbackCondition.broadcast();
}
+ // Wait without lock held
+ if (mCore->mConnectedApi == NATIVE_WINDOW_API_EGL) {
+ // Waiting here allows for two full buffers to be queued but not a
+ // third. In the event that frames take varying time, this makes a
+ // small trade-off in favor of latency rather than throughput.
+ mLastQueueBufferFence->waitForever("Throttling EGL Production");
+ mLastQueueBufferFence = fence;
+ }
+
return NO_ERROR;
}
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 4b3603e..235cbbd 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -245,6 +245,11 @@
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 0155007..a624663 100644
--- a/libs/input/Input.cpp
+++ b/libs/input/Input.cpp
@@ -424,7 +424,8 @@
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/KeyCharacterMap.cpp b/libs/input/KeyCharacterMap.cpp
index 732ebd0..dd01a93 100644
--- a/libs/input/KeyCharacterMap.cpp
+++ b/libs/input/KeyCharacterMap.cpp
@@ -332,33 +332,75 @@
if (usageCode) {
ssize_t index = mKeysByUsageCode.indexOfKey(usageCode);
if (index >= 0) {
-#if DEBUG_MAPPING
- ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
- scanCode, usageCode, *outKeyCode);
-#endif
*outKeyCode = mKeysByUsageCode.valueAt(index);
+#if DEBUG_MAPPING
+ ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
+ scanCode, usageCode, *outKeyCode);
+#endif
return OK;
}
}
if (scanCode) {
ssize_t index = mKeysByScanCode.indexOfKey(scanCode);
if (index >= 0) {
-#if DEBUG_MAPPING
- ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
- scanCode, usageCode, *outKeyCode);
-#endif
*outKeyCode = mKeysByScanCode.valueAt(index);
+#if DEBUG_MAPPING
+ ALOGD("mapKey: scanCode=%d, usageCode=0x%08x ~ Result keyCode=%d.",
+ scanCode, usageCode, *outKeyCode);
+#endif
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 @@
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 @@
behavior->metaState = metaState;
behavior->character = character;
behavior->fallbackKeyCode = fallbackKeyCode;
+ behavior->replacementKeyCode = replacementKeyCode;
if (lastBehavior) {
lastBehavior->next = behavior;
} else {
@@ -624,6 +668,7 @@
parcel->writeInt32(behavior->metaState);
parcel->writeInt32(behavior->character);
parcel->writeInt32(behavior->fallbackKeyCode);
+ parcel->writeInt32(behavior->replacementKeyCode);
}
parcel->writeInt32(0);
}
@@ -655,13 +700,14 @@
// --- 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 @@
Behavior behavior;
bool haveCharacter = false;
bool haveFallback = false;
+ bool haveReplacement = false;
do {
char ch = mTokenizer->peekChar();
@@ -939,6 +986,11 @@
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 @@
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 @@
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 @@
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 @@
~(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/Android.mk b/opengl/libs/Android.mk
index 7fb0f77..f389c94 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -103,11 +103,12 @@
include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= \
- GLES2/gl2.cpp.arm \
+LOCAL_SRC_FILES:= \
+ GLES2/gl2.cpp \
#
LOCAL_CLANG := false
+LOCAL_ARM_MODE := arm
LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libEGL
LOCAL_MODULE:= libGLESv2
@@ -122,14 +123,32 @@
# TODO: This is to work around b/20093774. Remove after root cause is fixed
LOCAL_LDFLAGS_arm += -Wl,--hash-style,both
-# Symlink libGLESv3.so -> libGLESv2.so
-# Platform modules should link against libGLESv2.so (-lGLESv2), but NDK apps
-# will be linked against libGLESv3.so.
-# Note we defer the evaluation of the LOCAL_POST_INSTALL_CMD,
-# so $(LOCAL_INSTALLED_MODULE) will be expanded to correct value,
-# even for both 32-bit and 64-bit installed files in multilib build.
-LOCAL_POST_INSTALL_CMD = \
- $(hide) ln -sf $(notdir $(LOCAL_INSTALLED_MODULE)) $(dir $(LOCAL_INSTALLED_MODULE))libGLESv3.so
+include $(BUILD_SHARED_LIBRARY)
+
+###############################################################################
+# Build the wrapper OpenGL ES 3.x library (this is just different name for v2)
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ GLES2/gl2.cpp \
+#
+
+LOCAL_CLANG := false
+LOCAL_ARM_MODE := arm
+LOCAL_SHARED_LIBRARIES += libcutils libutils liblog libEGL
+LOCAL_MODULE:= libGLESv3
+LOCAL_SHARED_LIBRARIES += libdl
+# we need to access the private Bionic header <bionic_tls.h>
+LOCAL_C_INCLUDES += bionic/libc/private
+
+LOCAL_CFLAGS += -DLOG_TAG=\"libGLESv3\"
+LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
+LOCAL_CFLAGS += -fvisibility=hidden
+
+# TODO: This is to work around b/20093774. Remove after root cause is fixed
+LOCAL_LDFLAGS_arm += -Wl,--hash-style,both
include $(BUILD_SHARED_LIBRARY)
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 @@
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 6b60c7c..5859606 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -438,10 +438,12 @@
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 @@
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 3ec4910..0f94c77 100644
--- a/services/inputflinger/EventHub.h
+++ b/services/inputflinger/EventHub.h
@@ -197,8 +197,9 @@
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;
@@ -285,8 +286,9 @@
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 36095bf..b2cbfe8 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -2177,13 +2177,7 @@
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;
}
@@ -2208,8 +2202,18 @@
|| (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.
@@ -2262,6 +2266,12 @@
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;
@@ -2289,7 +2299,7 @@
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);
}
@@ -3543,8 +3553,10 @@
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 7cb4680..30c84b1 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -1154,8 +1154,7 @@
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/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 @@
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 @@
if (outFlags) {
*outFlags = key->flags;
}
+ if (outMetaState) {
+ *outMetaState = metaState;
+ }
return OK;
}
}
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 13d44f3..bdf8f74 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -88,21 +88,22 @@
mPowerMode(HWC_POWER_MODE_OFF),
mActiveConfig(0)
{
- mNativeWindow = new Surface(producer, false);
+ Surface* surface;
+ mNativeWindow = surface = new Surface(producer, false);
ANativeWindow* const window = mNativeWindow.get();
/*
* Create our display's surface
*/
- EGLSurface surface;
+ EGLSurface eglSurface;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (config == EGL_NO_CONFIG) {
config = RenderEngine::chooseEglConfig(display, format);
}
- surface = eglCreateWindowSurface(display, config, window, NULL);
- eglQuerySurface(display, surface, EGL_WIDTH, &mDisplayWidth);
- eglQuerySurface(display, surface, EGL_HEIGHT, &mDisplayHeight);
+ eglSurface = eglCreateWindowSurface(display, config, window, NULL);
+ eglQuerySurface(display, eglSurface, EGL_WIDTH, &mDisplayWidth);
+ eglQuerySurface(display, eglSurface, EGL_HEIGHT, &mDisplayHeight);
// Make sure that composition can never be stalled by a virtual display
// consumer that isn't processing buffers fast enough. We have to do this
@@ -116,7 +117,7 @@
mConfig = config;
mDisplay = display;
- mSurface = surface;
+ mSurface = eglSurface;
mFormat = format;
mPageFlipCount = 0;
mViewport.makeInvalid();
@@ -142,6 +143,10 @@
// initialize the display orientation transform.
setProjection(DisplayState::eOrientationDefault, mViewport, mFrame);
+
+#ifdef NUM_FRAMEBUFFER_SURFACE_BUFFERS
+ surface->allocateBuffers();
+#endif
}
DisplayDevice::~DisplayDevice() {