diff options
-rw-r--r-- | cmds/installd/commands.c | 137 | ||||
-rw-r--r-- | cmds/installd/installd.c | 7 | ||||
-rw-r--r-- | cmds/installd/installd.h | 2 | ||||
-rw-r--r-- | include/android/sensor.h | 14 | ||||
-rw-r--r-- | include/media/openmax/OMX_Audio.h | 1 | ||||
-rw-r--r-- | include/media/openmax/OMX_AudioExt.h | 14 | ||||
-rw-r--r-- | include/media/openmax/OMX_IndexExt.h | 1 | ||||
-rw-r--r-- | libs/gui/BufferQueueProducer.cpp | 4 | ||||
-rw-r--r-- | libs/gui/SensorManager.cpp | 13 | ||||
-rw-r--r-- | opengl/libs/EGL/eglApi.cpp | 9 | ||||
-rw-r--r-- | services/inputflinger/InputDispatcher.cpp | 46 | ||||
-rw-r--r-- | services/inputflinger/InputDispatcher.h | 14 | ||||
-rw-r--r-- | services/surfaceflinger/DisplayHardware/HWComposer.cpp | 2 | ||||
-rw-r--r-- | services/surfaceflinger/Layer.cpp | 10 |
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; |