summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/installd/commands.c137
-rw-r--r--cmds/installd/installd.c7
-rw-r--r--cmds/installd/installd.h2
-rw-r--r--include/android/sensor.h14
-rw-r--r--include/media/openmax/OMX_Audio.h1
-rw-r--r--include/media/openmax/OMX_AudioExt.h14
-rw-r--r--include/media/openmax/OMX_IndexExt.h1
-rw-r--r--libs/gui/BufferQueueProducer.cpp4
-rw-r--r--libs/gui/SensorManager.cpp13
-rw-r--r--opengl/libs/EGL/eglApi.cpp9
-rw-r--r--services/inputflinger/InputDispatcher.cpp46
-rw-r--r--services/inputflinger/InputDispatcher.h14
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp2
-rw-r--r--services/surfaceflinger/Layer.cpp10
14 files changed, 231 insertions, 43 deletions
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index ba8edf2..bd721c8 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -570,7 +570,6 @@ done:
return 0;
}
-
int create_cache_path(char path[PKG_PATH_MAX], const char *src, const char *instruction_set)
{
char *tmp;
@@ -633,6 +632,46 @@ static void run_dexopt(int zip_fd, int odex_fd, const char* input_file_name,
ALOGE("execl(%s) failed: %s\n", DEX_OPT_BIN, strerror(errno));
}
+static void run_patchoat(int input_fd, int oat_fd, const char* input_file_name,
+ const char* output_file_name, const char *pkgname, const char *instruction_set)
+{
+ static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig
+ static const unsigned int MAX_INSTRUCTION_SET_LEN = 32;
+
+ static const char* PATCHOAT_BIN = "/system/bin/patchoat";
+ if (strlen(instruction_set) >= MAX_INSTRUCTION_SET_LEN) {
+ ALOGE("Instruction set %s longer than max length of %d",
+ instruction_set, MAX_INSTRUCTION_SET_LEN);
+ return;
+ }
+
+ /* input_file_name/input_fd should be the .odex/.oat file that is precompiled. I think*/
+ char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN];
+ char output_oat_fd_arg[strlen("--output-oat-fd=") + MAX_INT_LEN];
+ char input_oat_fd_arg[strlen("--input-oat-fd=") + MAX_INT_LEN];
+ const char* patched_image_location_arg = "--patched-image-location=/system/framework/boot.art";
+ // The caller has already gotten all the locks we need.
+ const char* no_lock_arg = "--no-lock-output";
+ sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
+ sprintf(output_oat_fd_arg, "--output-oat-fd=%d", oat_fd);
+ sprintf(input_oat_fd_arg, "--input-oat-fd=%d", input_fd);
+ ALOGE("Running %s isa=%s in-fd=%d (%s) out-fd=%d (%s)\n",
+ PATCHOAT_BIN, instruction_set, input_fd, input_file_name, oat_fd, output_file_name);
+
+ /* patchoat, patched-image-location, no-lock, isa, input-fd, output-fd */
+ char* argv[7];
+ argv[0] = (char*) PATCHOAT_BIN;
+ argv[1] = (char*) patched_image_location_arg;
+ argv[2] = (char*) no_lock_arg;
+ argv[3] = instruction_set_arg;
+ argv[4] = output_oat_fd_arg;
+ argv[5] = input_oat_fd_arg;
+ argv[6] = NULL;
+
+ execv(PATCHOAT_BIN, (char* const *)argv);
+ ALOGE("execv(%s) failed: %s\n", PATCHOAT_BIN, strerror(errno));
+}
+
static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
const char* output_file_name, const char *pkgname, const char *instruction_set)
{
@@ -645,10 +684,21 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
char dex2oat_Xmx_flag[PROPERTY_VALUE_MAX];
bool have_dex2oat_Xmx_flag = property_get("dalvik.vm.dex2oat-Xmx", dex2oat_Xmx_flag, NULL) > 0;
+ char dex2oat_compiler_filter_flag[PROPERTY_VALUE_MAX];
+ bool have_dex2oat_compiler_filter_flag = property_get("dalvik.vm.dex2oat-filter",
+ dex2oat_compiler_filter_flag, NULL) > 0;
+
char dex2oat_flags[PROPERTY_VALUE_MAX];
bool have_dex2oat_flags = property_get("dalvik.vm.dex2oat-flags", dex2oat_flags, NULL) > 0;
ALOGV("dalvik.vm.dex2oat-flags=%s\n", dex2oat_flags);
+ // If we booting without the real /data, don't spend time compiling.
+ char vold_decrypt[PROPERTY_VALUE_MAX];
+ bool have_vold_decrypt = property_get("vold.decrypt", vold_decrypt, "") > 0;
+ bool skip_compilation = (have_vold_decrypt &&
+ (strcmp(vold_decrypt, "trigger_restart_min_framework") == 0 ||
+ (strcmp(vold_decrypt, "1") == 0)));
+
static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
static const char* RUNTIME_ARG = "--runtime-arg";
@@ -671,6 +721,7 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
char top_k_profile_threshold_arg[strlen("--top-k-profile-threshold=") + PROPERTY_VALUE_MAX];
char dex2oat_Xms_arg[strlen("-Xms") + PROPERTY_VALUE_MAX];
char dex2oat_Xmx_arg[strlen("-Xmx") + PROPERTY_VALUE_MAX];
+ char dex2oat_compiler_filter_arg[strlen("--compiler-filter=") + PROPERTY_VALUE_MAX];
sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
@@ -702,6 +753,12 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
if (have_dex2oat_Xmx_flag) {
sprintf(dex2oat_Xmx_arg, "-Xmx%s", dex2oat_Xmx_flag);
}
+ if (skip_compilation) {
+ strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=interpret-only");
+ have_dex2oat_compiler_filter_flag = true;
+ } else if (have_dex2oat_compiler_filter_flag) {
+ sprintf(dex2oat_compiler_filter_arg, "--compiler-filter=%s", dex2oat_compiler_filter_flag);
+ }
ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
@@ -710,6 +767,7 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
+ (have_top_k_profile_threshold ? 1 : 0)
+ (have_dex2oat_Xms_flag ? 2 : 0)
+ (have_dex2oat_Xmx_flag ? 2 : 0)
+ + (have_dex2oat_compiler_filter_flag ? 1 : 0)
+ (have_dex2oat_flags ? 1 : 0)];
int i = 0;
argv[i++] = (char*)DEX2OAT_BIN;
@@ -732,6 +790,9 @@ static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
argv[i++] = (char*)RUNTIME_ARG;
argv[i++] = dex2oat_Xmx_arg;
}
+ if (have_dex2oat_compiler_filter_flag) {
+ argv[i++] = dex2oat_compiler_filter_arg;
+ }
if (have_dex2oat_flags) {
argv[i++] = dex2oat_flags;
}
@@ -769,14 +830,17 @@ static int wait_child(pid_t pid)
}
int dexopt(const char *apk_path, uid_t uid, int is_public,
- const char *pkgname, const char *instruction_set)
+ const char *pkgname, const char *instruction_set,
+ int is_patchoat)
{
struct utimbuf ut;
- struct stat apk_stat, dex_stat;
+ struct stat input_stat, dex_stat;
char out_path[PKG_PATH_MAX];
char persist_sys_dalvik_vm_lib[PROPERTY_VALUE_MAX];
char *end;
- int res, zip_fd=-1, out_fd=-1;
+ const char *input_file;
+ char in_odex_path[PKG_PATH_MAX];
+ int res, input_fd=-1, out_fd=-1;
if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
return -1;
@@ -785,12 +849,20 @@ int dexopt(const char *apk_path, uid_t uid, int is_public,
/* The command to run depend on the value of persist.sys.dalvik.vm.lib */
property_get("persist.sys.dalvik.vm.lib.2", persist_sys_dalvik_vm_lib, "libart.so");
+ if (is_patchoat && strncmp(persist_sys_dalvik_vm_lib, "libart", 6) != 0) {
+ /* We may only patch if we are libart */
+ ALOGE("Patching is only supported in libart\n");
+ return -1;
+ }
+
/* Before anything else: is there a .odex file? If so, we have
* precompiled the apk and there is nothing to do here.
+ *
+ * We skip this if we are doing a patchoat.
*/
strcpy(out_path, apk_path);
end = strrchr(out_path, '.');
- if (end != NULL) {
+ if (end != NULL && !is_patchoat) {
strcpy(end, ".odex");
if (stat(out_path, &dex_stat) == 0) {
return 0;
@@ -801,12 +873,33 @@ int dexopt(const char *apk_path, uid_t uid, int is_public,
return -1;
}
- memset(&apk_stat, 0, sizeof(apk_stat));
- stat(apk_path, &apk_stat);
+ if (is_patchoat) {
+ /* /system/framework/whatever.jar -> /system/framework/<isa>/whatever.odex */
+ strcpy(in_odex_path, apk_path);
+ end = strrchr(in_odex_path, '/');
+ if (end == NULL) {
+ ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path);
+ return -1;
+ }
+ const char *apk_end = apk_path + (end - in_odex_path); // strrchr(apk_path, '/');
+ strcpy(end + 1, instruction_set); // in_odex_path now is /system/framework/<isa>\0
+ strcat(in_odex_path, apk_end);
+ end = strrchr(in_odex_path, '.');
+ if (end == NULL) {
+ return -1;
+ }
+ strcpy(end + 1, "odex");
+ input_file = in_odex_path;
+ } else {
+ input_file = apk_path;
+ }
+
+ memset(&input_stat, 0, sizeof(input_stat));
+ stat(input_file, &input_stat);
- zip_fd = open(apk_path, O_RDONLY, 0);
- if (zip_fd < 0) {
- ALOGE("installd cannot open '%s' for input during dexopt\n", apk_path);
+ input_fd = open(input_file, O_RDONLY, 0);
+ if (input_fd < 0) {
+ ALOGE("installd cannot open '%s' for input during dexopt\n", input_file);
return -1;
}
@@ -833,7 +926,7 @@ int dexopt(const char *apk_path, uid_t uid, int is_public,
}
- ALOGV("DexInv: --- BEGIN '%s' ---\n", apk_path);
+ ALOGV("DexInv: --- BEGIN '%s' ---\n", input_file);
pid_t pid;
pid = fork();
@@ -863,9 +956,13 @@ int dexopt(const char *apk_path, uid_t uid, int is_public,
}
if (strncmp(persist_sys_dalvik_vm_lib, "libdvm", 6) == 0) {
- run_dexopt(zip_fd, out_fd, apk_path, out_path);
+ run_dexopt(input_fd, out_fd, input_file, out_path);
} else if (strncmp(persist_sys_dalvik_vm_lib, "libart", 6) == 0) {
- run_dex2oat(zip_fd, out_fd, apk_path, out_path, pkgname, instruction_set);
+ if (is_patchoat) {
+ run_patchoat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set);
+ } else {
+ run_dex2oat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set);
+ }
} else {
exit(69); /* Unexpected persist.sys.dalvik.vm.lib value */
}
@@ -873,19 +970,19 @@ int dexopt(const char *apk_path, uid_t uid, int is_public,
} else {
res = wait_child(pid);
if (res == 0) {
- ALOGV("DexInv: --- END '%s' (success) ---\n", apk_path);
+ ALOGV("DexInv: --- END '%s' (success) ---\n", input_file);
} else {
- ALOGE("DexInv: --- END '%s' --- status=0x%04x, process failed\n", apk_path, res);
+ ALOGE("DexInv: --- END '%s' --- status=0x%04x, process failed\n", input_file, res);
goto fail;
}
}
- ut.actime = apk_stat.st_atime;
- ut.modtime = apk_stat.st_mtime;
+ ut.actime = input_stat.st_atime;
+ ut.modtime = input_stat.st_mtime;
utime(out_path, &ut);
close(out_fd);
- close(zip_fd);
+ close(input_fd);
return 0;
fail:
@@ -893,8 +990,8 @@ fail:
close(out_fd);
unlink(out_path);
}
- if (zip_fd >= 0) {
- close(zip_fd);
+ if (input_fd >= 0) {
+ close(input_fd);
}
return -1;
}
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index 62579b9..746ce57 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -39,7 +39,7 @@ static int do_install(char **arg, char reply[REPLY_MAX])
static int do_dexopt(char **arg, char reply[REPLY_MAX])
{
/* apk_path, uid, is_public, pkgname, instruction_set */
- return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4]);
+ return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4], 0);
}
static int do_move_dex(char **arg, char reply[REPLY_MAX])
@@ -151,6 +151,10 @@ static int do_prune_dex_cache(char **arg __attribute__((unused)),
return prune_dex_cache(arg[0] /* subdirectory name */);
}
+static int do_patchoat(char **arg, char reply[REPLY_MAX]) {
+ return dexopt(arg[0], atoi(arg[1]), atoi(arg[2]), arg[3], arg[4], 1);
+}
+
struct cmdinfo {
const char *name;
unsigned numargs;
@@ -179,6 +183,7 @@ struct cmdinfo cmds[] = {
{ "idmap", 3, do_idmap },
{ "restorecondata", 3, do_restorecon_data },
{ "prunedexcache", 1, do_prune_dex_cache },
+ { "patchoat", 5, do_patchoat },
};
static int readx(int s, void *_buf, int count)
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index 7a5da98..9d420bd 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -217,7 +217,7 @@ int get_size(const char *pkgname, userid_t userid, const char *apkpath, const ch
int64_t *codesize, int64_t *datasize, int64_t *cachesize, int64_t *asecsize);
int free_cache(int64_t free_size);
int dexopt(const char *apk_path, uid_t uid, int is_public, const char *pkgName,
- const char *instruction_set);
+ const char *instruction_set, int should_relocate);
int movefiles();
int linklib(const char* target, const char* source, int userId);
int idmap(const char *target_path, const char *overlay_path, uid_t uid);
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 77a5a1c..d58c460 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -210,11 +210,18 @@ int ASensorManager_getSensorList(ASensorManager* manager, ASensorList* list);
/*
* Returns the default sensor for the given type, or NULL if no sensor
- * of that type exist.
+ * of that type exists.
*/
ASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type);
/*
+ * Returns the default sensor with the given type and wakeUp properties or NULL if no sensor
+ * of this type and wakeUp properties exists.
+ */
+ASensor const* ASensorManager_getDefaultSensorEx(ASensorManager* manager, int type,
+ bool wakeUp);
+
+/*
* Creates a new sensor event queue and associate it with a looper.
*/
ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager,
@@ -321,6 +328,11 @@ const char* ASensor_getStringType(ASensor const* sensor);
*/
int ASensor_getReportingMode(ASensor const* sensor);
+/*
+ * Returns true if this is a wake up sensor, false otherwise.
+ */
+bool ASensor_isWakeUpSensor(ASensor const* sensor);
+
#ifdef __cplusplus
};
#endif
diff --git a/include/media/openmax/OMX_Audio.h b/include/media/openmax/OMX_Audio.h
index 89ce0fc..f4cb643 100644
--- a/include/media/openmax/OMX_Audio.h
+++ b/include/media/openmax/OMX_Audio.h
@@ -278,6 +278,7 @@ typedef enum OMX_AUDIO_AACPROFILETYPE{
#define OMX_AUDIO_AACToolTNS 0x00000004 /**< TNS: Temporal Noise Shaping tool allowed or active */
#define OMX_AUDIO_AACToolPNS 0x00000008 /**< PNS: MPEG-4 Perceptual Noise substitution tool allowed or active */
#define OMX_AUDIO_AACToolLTP 0x00000010 /**< LTP: MPEG-4 Long Term Prediction tool allowed or active */
+#define OMX_AUDIO_AACToolVendor 0x00010000 /**< NOT A KHRONOS VALUE, offset for vendor-specific additions */
#define OMX_AUDIO_AACToolAll 0x7FFFFFFF /**< all AAC tools allowed or active (*/
/** MPEG-4 AAC error resilience (ER) tool usage (for nAACERtools in OMX_AUDIO_PARAM_AACPROFILETYPE).
diff --git a/include/media/openmax/OMX_AudioExt.h b/include/media/openmax/OMX_AudioExt.h
index dc6457b..8a2c4de 100644
--- a/include/media/openmax/OMX_AudioExt.h
+++ b/include/media/openmax/OMX_AudioExt.h
@@ -40,6 +40,9 @@ extern "C" {
*/
#include <OMX_Core.h>
+#define OMX_AUDIO_AACToolAndroidSSBR (OMX_AUDIO_AACToolVendor << 0) /**< SSBR: MPEG-4 Single-rate (downsampled) Spectral Band Replication tool allowed or active */
+#define OMX_AUDIO_AACToolAndroidDSBR (OMX_AUDIO_AACToolVendor << 1) /**< DSBR: MPEG-4 Dual-rate Spectral Band Replication tool allowed or active */
+
typedef enum OMX_AUDIO_CODINGEXTTYPE {
OMX_AUDIO_CodingAndroidUnused = OMX_AUDIO_CodingKhronosExtensions + 0x00100000,
OMX_AUDIO_CodingAndroidAC3, /**< AC3 encoded data */
@@ -69,6 +72,17 @@ typedef struct OMX_AUDIO_PARAM_ANDROID_OPUSTYPE {
limit the audio signal. Use 0 to let encoder decide */
} OMX_AUDIO_PARAM_ANDROID_OPUSTYPE;
+typedef struct OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE {
+ OMX_U32 nSize; /**< size of the structure in bytes */
+ OMX_VERSIONTYPE nVersion; /**< OMX specification version information */
+ OMX_S32 nMaxOutputChannels; /**< Maximum channel count to be output, -1 if unspecified, 0 if downmixing disabled */
+ OMX_S32 nDrcCut; /**< The DRC attenuation factor, between 0 and 127, -1 if unspecified */
+ OMX_S32 nDrcBoost; /**< The DRC amplification factor, between 0 and 127, -1 if unspecified */
+ OMX_S32 nHeavyCompression; /**< 0 for light compression, 1 for heavy compression, -1 if unspecified */
+ OMX_S32 nTargetReferenceLevel; /**< Target reference level, between 0 and 127, -1 if unspecified */
+ OMX_S32 nEncodedTargetLevel; /**< Target reference level assumed at the encoder, between 0 and 127, -1 if unspecified */
+} OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE;
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/include/media/openmax/OMX_IndexExt.h b/include/media/openmax/OMX_IndexExt.h
index 7070809..6cd774b 100644
--- a/include/media/openmax/OMX_IndexExt.h
+++ b/include/media/openmax/OMX_IndexExt.h
@@ -59,6 +59,7 @@ typedef enum OMX_INDEXEXTTYPE {
OMX_IndexExtAudioStartUnused = OMX_IndexKhronosExtensions + 0x00400000,
OMX_IndexParamAudioAndroidAc3, /**< reference: OMX_AUDIO_PARAM_ANDROID_AC3TYPE */
OMX_IndexParamAudioAndroidOpus, /**< reference: OMX_AUDIO_PARAM_ANDROID_OPUSTYPE */
+ OMX_IndexParamAudioAndroidAacPresentation, /**< reference: OMX_AUDIO_PARAM_ANDROID_AACPRESENTATIONTYPE */
/* Image parameters and configurations */
OMX_IndexExtImageStartUnused = OMX_IndexKhronosExtensions + 0x00500000,
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index cbca3ac..a53775f 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -830,8 +830,8 @@ status_t BufferQueueProducer::disconnect(int api) {
mCore->mSidebandStream.clear();
mCore->mDequeueCondition.broadcast();
listener = mCore->mConsumerListener;
- } else if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
- BQ_LOGE("disconnect(P): still connected to another API "
+ } else {
+ BQ_LOGE("disconnect(P): connected to another API "
"(cur=%d req=%d)", mCore->mConnectedApi, api);
status = BAD_VALUE;
}
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index b80da56..7b4fa2f 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -116,12 +116,23 @@ Sensor const* SensorManager::getDefaultSensor(int type)
{
Mutex::Autolock _l(mLock);
if (assertStateLocked() == NO_ERROR) {
+ bool wakeUpSensor = false;
+ // For the following sensor types, return a wake-up sensor. These types are by default
+ // defined as wake-up sensors. For the rest of the sensor types defined in sensors.h return
+ // a non_wake-up version.
+ if (type == SENSOR_TYPE_PROXIMITY || type == SENSOR_TYPE_SIGNIFICANT_MOTION ||
+ type == SENSOR_TYPE_TILT_DETECTOR || type == SENSOR_TYPE_WAKE_GESTURE ||
+ type == SENSOR_TYPE_GLANCE_GESTURE || type == SENSOR_TYPE_PICK_UP_GESTURE) {
+ wakeUpSensor = true;
+ }
// For now we just return the first sensor of that type we find.
// in the future it will make sense to let the SensorService make
// that decision.
for (size_t i=0 ; i<mSensors.size() ; i++) {
- if (mSensorList[i]->getType() == type)
+ if (mSensorList[i]->getType() == type &&
+ mSensorList[i]->isWakeUpSensor() == wakeUpSensor) {
return mSensorList[i];
+ }
}
}
return NULL;
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 99c01b7..6e77e45 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -572,15 +572,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/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index a750a3d..ce14f99 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -2366,9 +2366,38 @@ void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
policyFlags |= POLICY_FLAG_TRUSTED;
+ int32_t keyCode = args->keyCode;
+ if (metaState & AMETA_META_ON && args->action == AKEY_EVENT_ACTION_DOWN) {
+ int32_t newKeyCode = AKEYCODE_UNKNOWN;
+ if (keyCode == AKEYCODE_DEL) {
+ newKeyCode = AKEYCODE_BACK;
+ } else if (keyCode == AKEYCODE_ENTER) {
+ newKeyCode = AKEYCODE_HOME;
+ }
+ if (newKeyCode != AKEYCODE_UNKNOWN) {
+ AutoMutex _l(mLock);
+ struct KeyReplacement replacement = {keyCode, args->deviceId};
+ mReplacedKeys.add(replacement, newKeyCode);
+ keyCode = newKeyCode;
+ metaState &= ~AMETA_META_ON;
+ }
+ } else if (args->action == AKEY_EVENT_ACTION_UP) {
+ // In order to maintain a consistent stream of up and down events, check to see if the key
+ // going up is one we've replaced in a down event and haven't yet replaced in an up event,
+ // even if the modifier was released between the down and the up events.
+ AutoMutex _l(mLock);
+ struct KeyReplacement replacement = {keyCode, args->deviceId};
+ ssize_t index = mReplacedKeys.indexOfKey(replacement);
+ if (index >= 0) {
+ keyCode = mReplacedKeys.valueAt(index);
+ mReplacedKeys.removeItemsAt(index);
+ metaState &= ~AMETA_META_ON;
+ }
+ }
+
KeyEvent event;
event.initialize(args->deviceId, args->source, args->action,
- flags, args->keyCode, args->scanCode, metaState, 0,
+ flags, keyCode, args->scanCode, metaState, 0,
args->downTime, args->eventTime);
mPolicy->interceptKeyBeforeQueueing(&event, /*byref*/ policyFlags);
@@ -2391,7 +2420,7 @@ void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
int32_t repeatCount = 0;
KeyEntry* newEntry = new KeyEntry(args->eventTime,
args->deviceId, args->source, policyFlags,
- args->action, flags, args->keyCode, args->scanCode,
+ args->action, flags, keyCode, args->scanCode,
metaState, repeatCount, args->downTime);
needWake = enqueueInboundEventLocked(newEntry);
@@ -3050,6 +3079,7 @@ void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
mTouchStatesByDisplay.clear();
mLastHoverWindowHandle.clear();
+ mReplacedKeys.clear();
}
void InputDispatcher::logDispatchStateLocked() {
@@ -3188,6 +3218,18 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
dump.append(INDENT "InboundQueue: <empty>\n");
}
+ if (!mReplacedKeys.isEmpty()) {
+ dump.append(INDENT "ReplacedKeys:\n");
+ for (size_t i = 0; i < mReplacedKeys.size(); i++) {
+ const KeyReplacement& replacement = mReplacedKeys.keyAt(i);
+ int32_t newKeyCode = mReplacedKeys.valueAt(i);
+ dump.appendFormat(INDENT2 "%zu: originalKeyCode=%d, deviceId=%d, newKeyCode=%d\n",
+ i, replacement.keyCode, replacement.deviceId, newKeyCode);
+ }
+ } else {
+ dump.append(INDENT "ReplacedKeys: <empty>\n");
+ }
+
if (!mConnectionsByFd.isEmpty()) {
dump.append(INDENT "Connections:\n");
for (size_t i = 0; i < mConnectionsByFd.size(); i++) {
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 9439124..0d15d7b 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -904,6 +904,20 @@ private:
void resetKeyRepeatLocked();
KeyEntry* synthesizeKeyRepeatLocked(nsecs_t currentTime);
+ // Key replacement tracking
+ struct KeyReplacement {
+ int32_t keyCode;
+ int32_t deviceId;
+ bool operator==(const KeyReplacement& rhs) const {
+ return keyCode == rhs.keyCode && deviceId == rhs.deviceId;
+ }
+ bool operator<(const KeyReplacement& rhs) const {
+ return keyCode != rhs.keyCode ? keyCode < rhs.keyCode : deviceId < rhs.deviceId;
+ }
+ };
+ // Maps the key code replaced, device id tuple to the key code it was replaced with
+ KeyedVector<KeyReplacement, int32_t> mReplacedKeys;
+
// Deferred command processing.
bool haveCommandsLocked() const;
bool runCommandsLockedInterruptible();
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 6769031..53409d1 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -376,7 +376,7 @@ status_t HWComposer::queryDisplayProperties(int disp) {
config.ydpi = values[i] / 1000.0f;
break;
default:
- ALOG_ASSERT(false, "unknown display attribute[%d] %#x",
+ ALOG_ASSERT(false, "unknown display attribute[%zu] %#x",
i, DISPLAY_ATTRIBUTES[i]);
break;
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index bbb5cfe..716d24e 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -332,16 +332,16 @@ FloatRect Layer::computeCrop(const sp<const DisplayDevice>& hw) const {
winHeight = s.active.w;
}
const Rect winCrop = activeCrop.transform(
- invTransform, s.active.w, s.active.h);
+ invTransform, winWidth, winHeight);
// below, crop is intersected with winCrop expressed in crop's coordinate space
float xScale = crop.getWidth() / float(winWidth);
float yScale = crop.getHeight() / float(winHeight);
- float insetL = winCrop.left * xScale;
- float insetT = winCrop.top * yScale;
- float insetR = (winWidth - winCrop.right ) * xScale;
- float insetB = (winHeight - winCrop.bottom) * yScale;
+ float insetL = winCrop.left * xScale;
+ float insetT = winCrop.top * yScale;
+ float insetR = (s.active.w - winCrop.right ) * xScale;
+ float insetB = (s.active.h - winCrop.bottom) * yScale;
crop.left += insetL;
crop.top += insetT;