Merge "SurfaceFlinger: Fix rect out-of-bounds checks"
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 8911570..974c865 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -73,7 +73,7 @@
}
} else {
if (S_ISDIR(libStat.st_mode)) {
- if (delete_dir_contents(libsymlink, 1, 0) < 0) {
+ if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
ALOGE("couldn't delete lib directory during install for: %s", libsymlink);
return -1;
}
@@ -176,6 +176,10 @@
return 0;
}
+static int lib_dir_matcher(const char* file_name, const int is_dir) {
+ return is_dir && !strcmp(file_name, "lib");
+}
+
int delete_user_data(const char *pkgname, userid_t userid)
{
char pkgdir[PKG_PATH_MAX];
@@ -184,7 +188,7 @@
return -1;
/* delete contents, excluding "lib", but not the directory itself */
- return delete_dir_contents(pkgdir, 0, "lib");
+ return delete_dir_contents(pkgdir, 0, &lib_dir_matcher);
}
int make_user_data(const char *pkgname, uid_t uid, userid_t userid, const char* seinfo)
@@ -225,7 +229,7 @@
}
} else {
if (S_ISDIR(libStat.st_mode)) {
- if (delete_dir_contents(libsymlink, 1, 0) < 0) {
+ if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
ALOGE("couldn't delete lib directory during install for non-primary: %s",
libsymlink);
unlink(pkgdir);
@@ -307,7 +311,7 @@
return -1;
/* delete contents, not the directory, no exceptions */
- return delete_dir_contents(cachedir, 0, 0);
+ return delete_dir_contents(cachedir, 0, NULL);
}
/* Try to ensure free_size bytes of storage are available.
@@ -622,12 +626,11 @@
const char* output_file_name, const char *pkgname, const char *instruction_set)
{
char dex2oat_flags[PROPERTY_VALUE_MAX];
- property_get("dalvik.vm.dex2oat-flags", dex2oat_flags, "");
+ bool have_dex2oat_flags = property_get("dalvik.vm.dex2oat-flags", dex2oat_flags, NULL) > 0;
ALOGV("dalvik.vm.dex2oat-flags=%s\n", dex2oat_flags);
- char profiler_prop[PROPERTY_VALUE_MAX];
- bool profiler = property_get("dalvik.vm.profiler", profiler_prop, "0")
- && (profiler_prop[0] == '1');
+ char prop_buf[PROPERTY_VALUE_MAX];
+ bool profiler = (property_get("dalvik.vm.profiler", prop_buf, "0") > 0) && (prop_buf[0] == '1');
static const char* DEX2OAT_BIN = "/system/bin/dex2oat";
static const int MAX_INT_LEN = 12; // '-'+10dig+'\0' -OR- 0x+8dig
@@ -642,9 +645,10 @@
char zip_fd_arg[strlen("--zip-fd=") + MAX_INT_LEN];
char zip_location_arg[strlen("--zip-location=") + PKG_PATH_MAX];
char oat_fd_arg[strlen("--oat-fd=") + MAX_INT_LEN];
- char oat_location_arg[strlen("--oat-name=") + PKG_PATH_MAX];
- char profile_file_arg[strlen("--profile-file=") + PKG_PATH_MAX];
+ char oat_location_arg[strlen("--oat-location=") + PKG_PATH_MAX];
char instruction_set_arg[strlen("--instruction-set=") + MAX_INSTRUCTION_SET_LEN];
+ char profile_file_arg[strlen("--profile-file=") + PKG_PATH_MAX];
+ char top_k_profile_threshold_arg[strlen("--top-k-profile-threshold=") + PROPERTY_VALUE_MAX];
sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
@@ -652,27 +656,49 @@
sprintf(oat_location_arg, "--oat-location=%s", output_file_name);
sprintf(instruction_set_arg, "--instruction-set=%s", instruction_set);
+ bool have_profile_file = false;
+ bool have_top_k_profile_threshold = false;
if (profiler && (strcmp(pkgname, "*") != 0)) {
char profile_file[PKG_PATH_MAX];
snprintf(profile_file, sizeof(profile_file), "%s/%s",
DALVIK_CACHE_PREFIX "profiles", pkgname);
struct stat st;
- if (stat(profile_file, &st) == -1) {
- strcpy(profile_file_arg, "--no-profile-file");
- } else {
+ if ((stat(profile_file, &st) == 0) && (st.st_size > 0)) {
sprintf(profile_file_arg, "--profile-file=%s", profile_file);
+ have_profile_file = true;
+ if (property_get("dalvik.vm.profile.top-k-thr", prop_buf, NULL) > 0) {
+ snprintf(top_k_profile_threshold_arg, sizeof(top_k_profile_threshold_arg),
+ "--top-k-profile-threshold=%s", prop_buf);
+ have_top_k_profile_threshold = true;
+ }
}
- } else {
- strcpy(profile_file_arg, "--no-profile-file");
}
ALOGV("Running %s in=%s out=%s\n", DEX2OAT_BIN, input_file_name, output_file_name);
- execl(DEX2OAT_BIN, DEX2OAT_BIN,
- zip_fd_arg, zip_location_arg,
- oat_fd_arg, oat_location_arg,
- profile_file_arg, instruction_set_arg,
- strlen(dex2oat_flags) > 0 ? dex2oat_flags : NULL,
- (char*) NULL);
+
+ char* argv[7 // program name, mandatory arguments and the final NULL
+ + (have_profile_file ? 1 : 0)
+ + (have_top_k_profile_threshold ? 1 : 0)
+ + (have_dex2oat_flags ? 1 : 0)];
+ int i = 0;
+ argv[i++] = (char*)DEX2OAT_BIN;
+ argv[i++] = zip_fd_arg;
+ argv[i++] = zip_location_arg;
+ argv[i++] = oat_fd_arg;
+ argv[i++] = oat_location_arg;
+ argv[i++] = instruction_set_arg;
+ if (have_profile_file) {
+ argv[i++] = profile_file_arg;
+ }
+ if (have_top_k_profile_threshold) {
+ argv[i++] = top_k_profile_threshold_arg;
+ }
+ if (have_dex2oat_flags) {
+ argv[i++] = dex2oat_flags;
+ }
+ argv[i] = NULL;
+
+ execv(DEX2OAT_BIN, (char* const *)argv);
ALOGE("execl(%s) failed: %s\n", DEX2OAT_BIN, strerror(errno));
}
@@ -1130,7 +1156,7 @@
}
} else {
if (S_ISDIR(libStat.st_mode)) {
- if (delete_dir_contents(libsymlink, 1, 0) < 0) {
+ if (delete_dir_contents(libsymlink, 1, NULL) < 0) {
rc = -1;
goto out;
}
@@ -1355,3 +1381,30 @@
free(userdir);
return ret;
}
+
+static int prune_dex_exclusion_predicate(const char *file_name, const int is_dir)
+{
+ // Don't exclude any directories, we want to inspect them
+ // recusively for files.
+ if (is_dir) {
+ return 0;
+ }
+
+
+ // Don't exclude regular files that start with the list
+ // of prefixes.
+ static const char data_app_prefix[] = "data@app@";
+ static const char data_priv_app_prefix[] = "data@priv-app@";
+ if (!strncmp(file_name, data_app_prefix, sizeof(data_app_prefix) - 1) ||
+ !strncmp(file_name, data_priv_app_prefix, sizeof(data_priv_app_prefix) - 1)) {
+ return 0;
+ }
+
+ // Exclude all regular files that don't start with the prefix "data@app@" or
+ // "data@priv-app@".
+ return 1;
+}
+
+int prune_dex_cache() {
+ return delete_dir_contents(DALVIK_CACHE_PREFIX, 0, &prune_dex_exclusion_predicate);
+}
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index f714836..4368a9e 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -140,6 +140,12 @@
/* pkgName, seinfo, uid*/
}
+static int do_prune_dex_cache(char **arg __attribute__((unused)),
+ char reply[REPLY_MAX] __attribute__((unused)))
+{
+ return prune_dex_cache();
+}
+
struct cmdinfo {
const char *name;
unsigned numargs;
@@ -166,6 +172,7 @@
{ "rmuser", 1, do_rm_user },
{ "idmap", 3, do_idmap },
{ "restorecondata", 3, do_restorecon_data },
+ { "prunedexcache", 0, do_prune_dex_cache },
};
static int readx(int s, void *_buf, int count)
diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h
index ff26e49..c1e6e0f 100644
--- a/cmds/installd/installd.h
+++ b/cmds/installd/installd.h
@@ -159,7 +159,7 @@
int delete_dir_contents(const char *pathname,
int also_delete_dir,
- const char *ignore);
+ int (*exclusion_predicate)(const char *name, const int is_dir));
int delete_dir_contents_fd(int dfd, const char *name);
@@ -220,3 +220,4 @@
int linklib(const char* target, const char* source, int userId);
int idmap(const char *target_path, const char *overlay_path, uid_t uid);
int restorecon_data();
+int prune_dex_cache();
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c
index 420ad5e..35172de 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.c
@@ -219,7 +219,8 @@
return 0;
}
-static int _delete_dir_contents(DIR *d, const char *ignore)
+static int _delete_dir_contents(DIR *d,
+ int (*exclusion_predicate)(const char *name, const int is_dir))
{
int result = 0;
struct dirent *de;
@@ -232,8 +233,10 @@
while ((de = readdir(d))) {
const char *name = de->d_name;
- /* skip the ignore name if provided */
- if (ignore && !strcmp(name, ignore)) continue;
+ /* check using the exclusion predicate, if provided */
+ if (exclusion_predicate && exclusion_predicate(name, (de->d_type == DT_DIR))) {
+ continue;
+ }
if (de->d_type == DT_DIR) {
int r, subfd;
@@ -258,7 +261,7 @@
result = -1;
continue;
}
- if (_delete_dir_contents(subdir, 0)) {
+ if (_delete_dir_contents(subdir, exclusion_predicate)) {
result = -1;
}
closedir(subdir);
@@ -279,7 +282,7 @@
int delete_dir_contents(const char *pathname,
int also_delete_dir,
- const char *ignore)
+ int (*exclusion_predicate)(const char*, const int))
{
int res = 0;
DIR *d;
@@ -289,7 +292,7 @@
ALOGE("Couldn't opendir %s: %s\n", pathname, strerror(errno));
return -errno;
}
- res = _delete_dir_contents(d, ignore);
+ res = _delete_dir_contents(d, exclusion_predicate);
closedir(d);
if (also_delete_dir) {
if (rmdir(pathname)) {
@@ -1036,50 +1039,27 @@
int create_profile_file(const char *pkgname, gid_t gid) {
const char *profile_dir = DALVIK_CACHE_PREFIX "profiles";
- struct stat profileStat;
char profile_file[PKG_PATH_MAX];
- // If we don't have a profile directory under dalvik-cache we need to create one.
- if (stat(profile_dir, &profileStat) < 0) {
- // Create the profile directory under dalvik-cache.
- if (mkdir(profile_dir, 0711) < 0) {
- ALOGE("cannot make profile dir '%s': %s\n", profile_dir, strerror(errno));
- return -1;
- }
-
- // Make the profile directory write-only for group and other. Owner can rwx it.
- if (chmod(profile_dir, 0711) < 0) {
- ALOGE("cannot chown profile dir '%s': %s\n", profile_dir, strerror(errno));
- rmdir(profile_dir);
- return -1;
- }
-
- if (selinux_android_restorecon(profile_dir, 0) < 0) {
- ALOGE("cannot restorecon profile dir '%s': %s\n", profile_dir, strerror(errno));
- rmdir(profile_dir);
- return -1;
- }
- }
-
snprintf(profile_file, sizeof(profile_file), "%s/%s", profile_dir, pkgname);
// The 'system' user needs to be able to read the profile to determine if dex2oat
// needs to be run. This is done in dalvik.system.DexFile.isDexOptNeededInternal(). So
- // we make it world readable. Not a problem since the dalvik cache is world
- // readable anyway.
+ // we assign ownership to AID_SYSTEM and ensure it's not world-readable.
- int fd = open(profile_file, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0664);
+ int fd = open(profile_file, O_WRONLY | O_CREAT | O_NOFOLLOW | O_CLOEXEC, 0660);
- // Open will fail if the file already exists. We want to ignore that.
+ // Always set the uid/gid/permissions. The file could have been previously created
+ // with different permissions.
if (fd >= 0) {
- if (fchown(fd, -1, gid) < 0) {
+ if (fchown(fd, AID_SYSTEM, gid) < 0) {
ALOGE("cannot chown profile file '%s': %s\n", profile_file, strerror(errno));
close(fd);
unlink(profile_file);
return -1;
}
- if (fchmod(fd, 0664) < 0) {
+ if (fchmod(fd, 0660) < 0) {
ALOGE("cannot chmod profile file '%s': %s\n", profile_file, strerror(errno));
close(fd);
unlink(profile_file);
diff --git a/cmds/servicemanager/Android.mk b/cmds/servicemanager/Android.mk
index 4ab8df6..155cfc5 100644
--- a/cmds/servicemanager/Android.mk
+++ b/cmds/servicemanager/Android.mk
@@ -18,7 +18,7 @@
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
-LOCAL_SHARED_LIBRARIES := liblog
+LOCAL_SHARED_LIBRARIES := liblog libselinux
LOCAL_SRC_FILES := service_manager.c binder.c
LOCAL_CFLAGS += $(svc_c_flags)
LOCAL_MODULE := servicemanager
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index 3200012..0d0ef00 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -8,6 +8,8 @@
#include <private/android_filesystem_config.h>
+#include <selinux/android.h>
+
#include "binder.h"
#if 0
@@ -52,6 +54,8 @@
{ AID_MEDIA, "common_time.config" },
{ AID_KEYSTORE, "android.security.keystore" },
{ AID_RADIO, "telecomm" },
+ { AID_RADIO, "isub" },
+ { AID_RADIO, "ims" },
};
uint32_t svcmgr_handle;
@@ -80,16 +84,67 @@
return 1;
}
-int svc_can_register(uid_t uid, const uint16_t *name)
+static struct selabel_handle* sehandle;
+
+static bool check_mac_perms(const char *name, pid_t spid)
+{
+ if (is_selinux_enabled() <= 0) {
+ return true;
+ }
+
+ bool allowed = false;
+
+ const char *class = "service_manager";
+ const char *perm = "add";
+
+ char *tctx = NULL;
+ char *sctx = NULL;
+
+ if (!sehandle) {
+ ALOGE("SELinux: Failed to find sehandle %s.\n", name);
+ return false;
+ }
+
+ if (getpidcon(spid, &sctx) < 0) {
+ ALOGE("SELinux: getpidcon failed to retrieve pid context.\n");
+ return false;
+ }
+
+ if (!sctx) {
+ ALOGE("SELinux: Failed to find sctx for %s.\n", name);
+ return false;
+ }
+
+ if (selabel_lookup(sehandle, &tctx, name, 1) != 0) {
+ ALOGE("SELinux: selabel_lookup failed to set tctx for %s.\n", name);
+ freecon(sctx);
+ return false;
+ }
+
+ if (!tctx) {
+ ALOGE("SELinux: Failed to find tctx for %s.\n", name);
+ freecon(sctx);
+ return false;
+ }
+
+ int result = selinux_check_access(sctx, tctx, class, perm, (void *) name);
+ allowed = (result == 0);
+
+ freecon(sctx);
+ freecon(tctx);
+ return allowed;
+}
+
+static int svc_can_register(uid_t uid, const uint16_t *name, pid_t spid)
{
size_t n;
if ((uid == 0) || (uid == AID_SYSTEM))
- return 1;
+ return check_mac_perms(str8(name), spid) ? 1 : 0;
for (n = 0; n < sizeof(allowed) / sizeof(allowed[0]); n++)
if ((uid == allowed[n].uid) && str16eq(name, allowed[n].name))
- return 1;
+ return check_mac_perms(str8(name), spid) ? 1 : 0;
return 0;
}
@@ -159,7 +214,8 @@
int do_add_service(struct binder_state *bs,
const uint16_t *s, size_t len,
- uint32_t handle, uid_t uid, int allow_isolated)
+ uint32_t handle, uid_t uid, int allow_isolated,
+ pid_t spid)
{
struct svcinfo *si;
@@ -169,7 +225,7 @@
if (!handle || (len == 0) || (len > 127))
return -1;
- if (!svc_can_register(uid, s)) {
+ if (!svc_can_register(uid, s, spid)) {
ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
str8(s), handle, uid);
return -1;
@@ -239,6 +295,14 @@
return -1;
}
+ if (sehandle && selinux_status_updated() > 0) {
+ struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
+ if (tmp_sehandle) {
+ selabel_close(sehandle);
+ sehandle = tmp_sehandle;
+ }
+ }
+
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
@@ -253,7 +317,8 @@
s = bio_get_string16(msg, &len);
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
- if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated))
+ if (do_add_service(bs, s, len, handle, txn->sender_euid,
+ allow_isolated, txn->sender_pid))
return -1;
break;
@@ -278,6 +343,13 @@
return 0;
}
+
+static int audit_callback(void *data, security_class_t cls, char *buf, size_t len)
+{
+ snprintf(buf, len, "service=%s", !data ? "NULL" : (char *)data);
+ return 0;
+}
+
int main(int argc, char **argv)
{
struct binder_state *bs;
@@ -293,6 +365,14 @@
return -1;
}
+ sehandle = selinux_android_service_context_handle();
+
+ union selinux_callback cb;
+ cb.func_audit = audit_callback;
+ selinux_set_callback(SELINUX_CB_AUDIT, cb);
+ cb.func_log = selinux_log_callback;
+ selinux_set_callback(SELINUX_CB_LOG, cb);
+
svcmgr_handle = BINDER_SERVICE_MANAGER;
binder_loop(bs, svcmgr_handler);
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 878f8ff..77a5a1c 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -74,6 +74,16 @@
};
/*
+ * Sensor Reporting Modes.
+ */
+enum {
+ AREPORTING_MODE_CONTINUOUS = 0,
+ AREPORTING_MODE_ON_CHANGE = 1,
+ AREPORTING_MODE_ONE_SHOT = 2,
+ AREPORTING_MODE_SPECIAL_TRIGGER = 3
+};
+
+/*
* A few useful constants
*/
@@ -306,6 +316,11 @@
*/
const char* ASensor_getStringType(ASensor const* sensor);
+/*
+ * Returns the reporting mode for this sensor. One of AREPORTING_MODE_* constants.
+ */
+int ASensor_getReportingMode(ASensor const* sensor);
+
#ifdef __cplusplus
};
#endif
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index 548fbf8..2ee99f8 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -97,7 +97,6 @@
status_t writeInt64(int64_t val);
status_t writeFloat(float val);
status_t writeDouble(double val);
- status_t writeIntPtr(intptr_t val);
status_t writeCString(const char* str);
status_t writeString8(const String8& str);
status_t writeString16(const String16& str);
diff --git a/include/gui/ISurfaceComposer.h b/include/gui/ISurfaceComposer.h
index 1581084..9f1937b 100644
--- a/include/gui/ISurfaceComposer.h
+++ b/include/gui/ISurfaceComposer.h
@@ -104,15 +104,11 @@
virtual bool authenticateSurfaceTexture(
const sp<IGraphicBufferProducer>& surface) const = 0;
- /* triggers screen off and waits for it to complete
+ /* set display power mode. depending on the mode, it can either trigger
+ * screen on, off or low power mode and wait for it to complete.
* requires ACCESS_SURFACE_FLINGER permission.
*/
- virtual void blank(const sp<IBinder>& display) = 0;
-
- /* triggers screen on and waits for it to complete
- * requires ACCESS_SURFACE_FLINGER permission.
- */
- virtual void unblank(const sp<IBinder>& display) = 0;
+ virtual void setPowerMode(const sp<IBinder>& display, int mode) = 0;
/* returns information for each configuration of the given display
* intended to be used to get information about built-in displays */
@@ -165,15 +161,14 @@
GET_BUILT_IN_DISPLAY,
SET_TRANSACTION_STATE,
AUTHENTICATE_SURFACE,
- BLANK,
- UNBLANK,
GET_DISPLAY_CONFIGS,
GET_ACTIVE_CONFIG,
SET_ACTIVE_CONFIG,
CONNECT_DISPLAY,
CAPTURE_SCREEN,
CLEAR_ANIMATION_FRAME_STATS,
- GET_ANIMATION_FRAME_STATS
+ GET_ANIMATION_FRAME_STATS,
+ SET_POWER_MODE,
};
virtual status_t onTransact(uint32_t code, const Parcel& data,
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
index c1c98b9..28a08e2 100644
--- a/include/gui/Sensor.h
+++ b/include/gui/Sensor.h
@@ -72,7 +72,9 @@
const String8& getStringType() const;
const String8& getRequiredPermission() const;
int32_t getMaxDelay() const;
+ int32_t getFlags() const;
bool isWakeUpSensor() const;
+ int32_t getReportingMode() const;
// LightFlattenable protocol
inline bool isFixedSize() const { return false; }
@@ -96,7 +98,7 @@
String8 mStringType;
String8 mRequiredPermission;
int32_t mMaxDelay;
- bool mWakeUpSensor;
+ int32_t mFlags;
static void flattenString8(void*& buffer, size_t& size, const String8& string8);
static bool unflattenString8(void const*& buffer, size_t& size, String8& outputString8);
};
diff --git a/include/gui/SurfaceComposerClient.h b/include/gui/SurfaceComposerClient.h
index e666329..65313df 100644
--- a/include/gui/SurfaceComposerClient.h
+++ b/include/gui/SurfaceComposerClient.h
@@ -82,11 +82,8 @@
// returned by getDisplayInfo
static status_t setActiveConfig(const sp<IBinder>& display, int id);
- /* triggers screen off and waits for it to complete */
- static void blankDisplay(const sp<IBinder>& display);
-
- /* triggers screen on and waits for it to complete */
- static void unblankDisplay(const sp<IBinder>& display);
+ /* Triggers screen on/off or low power mode and waits for it to complete */
+ static void setDisplayPowerMode(const sp<IBinder>& display, int mode);
// ------------------------------------------------------------------------
// surface creation / destruction
diff --git a/include/ui/DisplayInfo.h b/include/ui/DisplayInfo.h
index 3b5cd6d..799944f 100644
--- a/include/ui/DisplayInfo.h
+++ b/include/ui/DisplayInfo.h
@@ -19,6 +19,7 @@
#include <stdint.h>
#include <sys/types.h>
+#include <utils/Timers.h>
#include <ui/PixelFormat.h>
@@ -33,6 +34,8 @@
float density;
uint8_t orientation;
bool secure;
+ nsecs_t appVsyncOffset;
+ nsecs_t presentationDeadline;
};
/* Display orientations as defined in Surface.java and ISurfaceComposer.h. */
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index f0d8732..76504ce 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -679,11 +679,6 @@
#endif
-status_t Parcel::writeIntPtr(intptr_t val)
-{
- return writeAligned(val);
-}
-
status_t Parcel::writeCString(const char* str)
{
return write(str, strlen(str)+1);
diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp
index 85a7de7..0282834 100644
--- a/libs/gui/BitTube.cpp
+++ b/libs/gui/BitTube.cpp
@@ -145,7 +145,7 @@
// should never happen because of SOCK_SEQPACKET
LOG_ALWAYS_FATAL_IF((size >= 0) && (size % objSize),
- "BitTube::sendObjects(count=%d, size=%d), res=%d (partial events were sent!)",
+ "BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)",
count, objSize, size);
//ALOGE_IF(size<0, "error %d sending %d events", size, count);
@@ -160,7 +160,7 @@
// should never happen because of SOCK_SEQPACKET
LOG_ALWAYS_FATAL_IF((size >= 0) && (size % objSize),
- "BitTube::recvObjects(count=%d, size=%d), res=%d (partial events were received!)",
+ "BitTube::recvObjects(count=%zu, size=%zu), res=%zd (partial events were received!)",
count, objSize, size);
//ALOGE_IF(size<0, "error %d receiving %d events", size, count);
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index f1b8fa8..f19b6c7 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
#define LOG_TAG "ConsumerBase"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
@@ -191,7 +193,7 @@
mSlots[item->mBuf].mFrameNumber = item->mFrameNumber;
mSlots[item->mBuf].mFence = item->mFence;
- CB_LOGV("acquireBufferLocked: -> slot=%d/%llu",
+ CB_LOGV("acquireBufferLocked: -> slot=%d/%" PRIu64,
item->mBuf, item->mFrameNumber);
return OK;
@@ -242,7 +244,7 @@
return OK;
}
- CB_LOGV("releaseBufferLocked: slot=%d/%llu",
+ CB_LOGV("releaseBufferLocked: slot=%d/%" PRIu64,
slot, mSlots[slot].mFrameNumber);
status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber,
display, eglFence, mSlots[slot].mFence);
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index c6c88a9..4680168 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -205,20 +205,13 @@
return reply.readStrongBinder();
}
- virtual void blank(const sp<IBinder>& display)
+ virtual void setPowerMode(const sp<IBinder>& display, int mode)
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeStrongBinder(display);
- remote()->transact(BnSurfaceComposer::BLANK, data, &reply);
- }
-
- virtual void unblank(const sp<IBinder>& display)
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeStrongBinder(display);
- remote()->transact(BnSurfaceComposer::UNBLANK, data, &reply);
+ data.writeInt32(mode);
+ remote()->transact(BnSurfaceComposer::SET_POWER_MODE, data, &reply);
}
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
@@ -378,18 +371,6 @@
reply->writeStrongBinder(display);
return NO_ERROR;
}
- case BLANK: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> display = data.readStrongBinder();
- blank(display);
- return NO_ERROR;
- }
- case UNBLANK: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> display = data.readStrongBinder();
- unblank(display);
- return NO_ERROR;
- }
case GET_DISPLAY_CONFIGS: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
Vector<DisplayInfo> configs;
@@ -434,6 +415,13 @@
reply->writeInt32(result);
return NO_ERROR;
}
+ case SET_POWER_MODE: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IBinder> display = data.readStrongBinder();
+ int32_t mode = data.readInt32();
+ setPowerMode(display, mode);
+ return NO_ERROR;
+ }
default: {
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index f161aeb..1c0f303 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -36,7 +36,7 @@
: mHandle(0), mType(0),
mMinValue(0), mMaxValue(0), mResolution(0),
mPower(0), mMinDelay(0), mFifoReservedEventCount(0), mFifoMaxEventCount(0),
- mMaxDelay(0), mWakeUpSensor(false)
+ mMaxDelay(0), mFlags(0)
{
}
@@ -52,7 +52,7 @@
mResolution = hwSensor->resolution;
mPower = hwSensor->power;
mMinDelay = hwSensor->minDelay;
- mWakeUpSensor = false;
+ mFlags = 0;
// Set fifo event count zero for older devices which do not support batching. Fused
// sensors also have their fifo counts set to zero.
@@ -79,154 +79,177 @@
mMaxDelay = 0;
}
- // Ensure existing sensors have correct string type and required
- // permissions.
+ // Ensure existing sensors have correct string type, required permissions and reporting mode.
switch (mType) {
case SENSOR_TYPE_ACCELEROMETER:
mStringType = SENSOR_STRING_TYPE_ACCELEROMETER;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_AMBIENT_TEMPERATURE:
mStringType = SENSOR_STRING_TYPE_AMBIENT_TEMPERATURE;
+ mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
break;
case SENSOR_TYPE_GAME_ROTATION_VECTOR:
mStringType = SENSOR_STRING_TYPE_GAME_ROTATION_VECTOR;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR:
mStringType = SENSOR_STRING_TYPE_GEOMAGNETIC_ROTATION_VECTOR;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_GRAVITY:
mStringType = SENSOR_STRING_TYPE_GRAVITY;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_GYROSCOPE:
mStringType = SENSOR_STRING_TYPE_GYROSCOPE;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_GYROSCOPE_UNCALIBRATED:
mStringType = SENSOR_STRING_TYPE_GYROSCOPE_UNCALIBRATED;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_HEART_RATE:
mStringType = SENSOR_STRING_TYPE_HEART_RATE;
mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS;
+ mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
break;
case SENSOR_TYPE_LIGHT:
mStringType = SENSOR_STRING_TYPE_LIGHT;
+ mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
break;
case SENSOR_TYPE_LINEAR_ACCELERATION:
mStringType = SENSOR_STRING_TYPE_LINEAR_ACCELERATION;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_MAGNETIC_FIELD:
mStringType = SENSOR_STRING_TYPE_MAGNETIC_FIELD;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED:
mStringType = SENSOR_STRING_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_ORIENTATION:
mStringType = SENSOR_STRING_TYPE_ORIENTATION;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_PRESSURE:
mStringType = SENSOR_STRING_TYPE_PRESSURE;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_PROXIMITY:
mStringType = SENSOR_STRING_TYPE_PROXIMITY;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_ON_CHANGE_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_RELATIVE_HUMIDITY:
mStringType = SENSOR_STRING_TYPE_RELATIVE_HUMIDITY;
+ mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
break;
case SENSOR_TYPE_ROTATION_VECTOR:
mStringType = SENSOR_STRING_TYPE_ROTATION_VECTOR;
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
break;
case SENSOR_TYPE_SIGNIFICANT_MOTION:
mStringType = SENSOR_STRING_TYPE_SIGNIFICANT_MOTION;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_STEP_COUNTER:
mStringType = SENSOR_STRING_TYPE_STEP_COUNTER;
+ mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
break;
case SENSOR_TYPE_STEP_DETECTOR:
mStringType = SENSOR_STRING_TYPE_STEP_DETECTOR;
+ mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
break;
case SENSOR_TYPE_TEMPERATURE:
mStringType = SENSOR_STRING_TYPE_TEMPERATURE;
+ mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
break;
case SENSOR_TYPE_NON_WAKE_UP_PROXIMITY_SENSOR:
mStringType = SENSOR_STRING_TYPE_NON_WAKE_UP_PROXIMITY_SENSOR;
+ mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
break;
case SENSOR_TYPE_WAKE_UP_ACCELEROMETER:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_ACCELEROMETER;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_MAGNETIC_FIELD:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_MAGNETIC_FIELD;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_ORIENTATION:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_ORIENTATION;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_GYROSCOPE:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_GYROSCOPE;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_LIGHT:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_LIGHT;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_ON_CHANGE_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_PRESSURE:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_PRESSURE;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_GRAVITY:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_GRAVITY;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_LINEAR_ACCELERATION:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_LINEAR_ACCELERATION;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_ROTATION_VECTOR:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_ROTATION_VECTOR;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_RELATIVE_HUMIDITY:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_RELATIVE_HUMIDITY;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_SPECIAL_REPORTING_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_AMBIENT_TEMPERATURE:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_AMBIENT_TEMPERATURE;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_ON_CHANGE_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_MAGNETIC_FIELD_UNCALIBRATED:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_MAGNETIC_FIELD_UNCALIBRATED;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_GAME_ROTATION_VECTOR:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_GAME_ROTATION_VECTOR;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_GYROSCOPE_UNCALIBRATED:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_GYROSCOPE_UNCALIBRATED;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_STEP_DETECTOR:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_STEP_DETECTOR;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_SPECIAL_REPORTING_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_STEP_COUNTER:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_STEP_COUNTER;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_ON_CHANGE_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_GEOMAGNETIC_ROTATION_VECTOR:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_GEOMAGNETIC_ROTATION_VECTOR;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_CONTINUOUS_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_UP_HEART_RATE:
mStringType = SENSOR_STRING_TYPE_WAKE_UP_HEART_RATE;
mRequiredPermission = SENSOR_PERMISSION_BODY_SENSORS;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_ON_CHANGE_MODE | SENSOR_FLAG_WAKE_UP);
+ break;
+ case SENSOR_TYPE_WAKE_UP_TILT_DETECTOR:
+ mStringType = SENSOR_STRING_TYPE_WAKE_UP_TILT_DETECTOR;
+ mFlags |= (SENSOR_FLAG_SPECIAL_REPORTING_MODE | SENSOR_FLAG_WAKE_UP);
break;
case SENSOR_TYPE_WAKE_GESTURE:
mStringType = SENSOR_STRING_TYPE_WAKE_GESTURE;
- mWakeUpSensor = true;
+ mFlags |= (SENSOR_FLAG_ONE_SHOT_MODE | SENSOR_FLAG_WAKE_UP);
break;
default:
// Only pipe the stringType, requiredPermission and flags for custom sensors.
@@ -236,8 +259,19 @@
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_2 && hwSensor->requiredPermission) {
mRequiredPermission = hwSensor->requiredPermission;
}
+
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
- mWakeUpSensor = hwSensor->flags & SENSOR_FLAG_WAKE_UP;
+ mFlags = (int32_t) hwSensor->flags;
+ } else {
+ // This is an OEM defined sensor on an older HAL. Use minDelay to determine the
+ // reporting mode of the sensor.
+ if (mMinDelay > 0) {
+ mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+ } else if (mMinDelay == 0) {
+ mFlags |= SENSOR_FLAG_ON_CHANGE_MODE;
+ } else if (mMinDelay < 0) {
+ mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+ }
}
break;
}
@@ -311,8 +345,16 @@
return mMaxDelay;
}
+int32_t Sensor::getFlags() const {
+ return mFlags;
+}
+
bool Sensor::isWakeUpSensor() const {
- return mWakeUpSensor;
+ return mFlags & SENSOR_FLAG_WAKE_UP;
+}
+
+int32_t Sensor::getReportingMode() const {
+ return ((mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT);
}
size_t Sensor::getFlattenedSize() const
@@ -320,8 +362,7 @@
size_t fixedSize =
sizeof(int32_t) * 3 +
sizeof(float) * 4 +
- sizeof(int32_t) * 4 +
- sizeof(bool) * 1;
+ sizeof(int32_t) * 5;
size_t variableSize =
sizeof(uint32_t) + FlattenableUtils::align<4>(mName.length()) +
@@ -352,7 +393,7 @@
flattenString8(buffer, size, mStringType);
flattenString8(buffer, size, mRequiredPermission);
FlattenableUtils::write(buffer, size, mMaxDelay);
- FlattenableUtils::write(buffer, size, mWakeUpSensor);
+ FlattenableUtils::write(buffer, size, mFlags);
return NO_ERROR;
}
@@ -367,8 +408,7 @@
size_t fixedSize =
sizeof(int32_t) * 3 +
sizeof(float) * 4 +
- sizeof(int32_t) * 4 +
- sizeof(bool) * 1;
+ sizeof(int32_t) * 5;
if (size < fixedSize) {
return NO_MEMORY;
}
@@ -391,7 +431,7 @@
return NO_MEMORY;
}
FlattenableUtils::read(buffer, size, mMaxDelay);
- FlattenableUtils::read(buffer, size, mWakeUpSensor);
+ FlattenableUtils::read(buffer, size, mFlags);
return NO_ERROR;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index eedeca1..3bee3fc 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -655,12 +655,9 @@
return ComposerService::getComposerService()->setActiveConfig(display, id);
}
-void SurfaceComposerClient::blankDisplay(const sp<IBinder>& token) {
- ComposerService::getComposerService()->blank(token);
-}
-
-void SurfaceComposerClient::unblankDisplay(const sp<IBinder>& token) {
- ComposerService::getComposerService()->unblank(token);
+void SurfaceComposerClient::setDisplayPowerMode(const sp<IBinder>& token,
+ int mode) {
+ ComposerService::getComposerService()->setPowerMode(token, mode);
}
status_t SurfaceComposerClient::clearAnimationFrameStats() {
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 21fd443..090ee53 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -301,7 +301,7 @@
"action=0x%x, flags=0x%x, edgeFlags=0x%x, metaState=0x%x, buttonState=0x%x, "
"xOffset=%f, yOffset=%f, "
"xPrecision=%f, yPrecision=%f, downTime=%lld, eventTime=%lld, "
- "pointerCount=%d",
+ "pointerCount=%" PRIu32,
mChannel->getName().string(), seq,
deviceId, source, action, flags, edgeFlags, metaState, buttonState,
xOffset, yOffset, xPrecision, yPrecision, downTime, eventTime, pointerCount);
@@ -313,7 +313,7 @@
}
if (pointerCount > MAX_POINTERS || pointerCount < 1) {
- ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %"PRIu32".",
+ ALOGE("channel '%s' publisher ~ Invalid number of pointers provided: %" PRIu32 ".",
mChannel->getName().string(), pointerCount);
return BAD_VALUE;
}
diff --git a/opengl/tests/hwc/Android.mk b/opengl/tests/hwc/Android.mk
index 2fdfcf8..86e1d46 100644
--- a/opengl/tests/hwc/Android.mk
+++ b/opengl/tests/hwc/Android.mk
@@ -57,7 +57,6 @@
LOCAL_CFLAGS := -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
LOCAL_MODULE:= hwcStress
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativestresstest
LOCAL_MODULE_TAGS := tests
@@ -88,7 +87,6 @@
$(call include-path-for, opengl-tests-includes)
LOCAL_MODULE:= hwcRects
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativeutil
LOCAL_MODULE_TAGS := tests
@@ -119,7 +117,6 @@
$(call include-path-for, opengl-tests-includes)
LOCAL_MODULE:= hwcColorEquiv
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativeutil
LOCAL_MODULE_TAGS := tests
@@ -150,7 +147,6 @@
$(call include-path-for, opengl-tests-includes)
LOCAL_MODULE:= hwcCommit
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/nativebenchmark
LOCAL_MODULE_TAGS := tests
diff --git a/services/inputflinger/EventHub.cpp b/services/inputflinger/EventHub.cpp
index ac73c1f..f274631 100644
--- a/services/inputflinger/EventHub.cpp
+++ b/services/inputflinger/EventHub.cpp
@@ -14,6 +14,24 @@
* limitations under the License.
*/
+#include <assert.h>
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <memory.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <sys/limits.h>
+#include <sys/inotify.h>
+#include <sys/ioctl.h>
+#include <sys/sha1.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+
#define LOG_TAG "EventHub"
// #define LOG_NDEBUG 0
@@ -28,29 +46,10 @@
#include <utils/threads.h>
#include <utils/Errors.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <memory.h>
-#include <errno.h>
-#include <assert.h>
-
#include <input/KeyLayoutMap.h>
#include <input/KeyCharacterMap.h>
#include <input/VirtualKeyMap.h>
-#include <string.h>
-#include <stdint.h>
-#include <dirent.h>
-
-#include <sys/inotify.h>
-#include <sys/epoll.h>
-#include <sys/ioctl.h>
-#include <sys/limits.h>
-#include <sys/sha1.h>
-#include <sys/utsname.h>
-
/* this macro is used to tell if "bit" is set in "array"
* it selects a byte from the array, and does a boolean AND
* operation with a byte that only has the relevant bit set.
@@ -812,8 +811,8 @@
sizeof(struct input_event) * capacity);
if (readSize == 0 || (readSize < 0 && errno == ENODEV)) {
// Device was removed before INotify noticed.
- ALOGW("could not get event, removed? (fd: %d size: %d bufferSize: %d "
- "capacity: %zu errno: %d)\n",
+ ALOGW("could not get event, removed? (fd: %d size: %" PRId32
+ " bufferSize: %zu capacity: %zu errno: %d)\n",
device->fd, readSize, bufferSize, capacity, errno);
deviceChanged = true;
closeDeviceLocked(device);
@@ -873,7 +872,7 @@
// system call that also queries ktime_get_ts().
event->when = nsecs_t(iev.time.tv_sec) * 1000000000LL
+ nsecs_t(iev.time.tv_usec) * 1000LL;
- ALOGV("event time %lld, now %lld", event->when, now);
+ ALOGV("event time %" PRId64 ", now %" PRId64, event->when, now);
// Bug 7291243: Add a guard in case the kernel generates timestamps
// that appear to be far into the future because they were generated
@@ -897,14 +896,16 @@
ALOGW("An input event from %s has a timestamp that appears to "
"have been generated using the wrong clock source "
"(expected CLOCK_MONOTONIC): "
- "event time %lld, current time %lld, call time %lld. "
+ "event time %" PRId64 ", current time %" PRId64
+ ", call time %" PRId64 ". "
"Using current time instead.",
device->path.string(), event->when, time, now);
event->when = time;
} else {
ALOGV("Event time is ok but failed the fast path and required "
"an extra call to systemTime: "
- "event time %lld, current time %lld, call time %lld.",
+ "event time %" PRId64 ", current time %" PRId64
+ ", call time %" PRId64 ".",
event->when, time, now);
}
}
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 01dbdfb..3934509 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-#include <stdint.h>
+#include <inttypes.h>
#include <math.h>
+#include <stdint.h>
#include <sys/types.h>
#include <utils/Atomic.h>
@@ -134,11 +135,11 @@
Info& info( mActivationCount.editValueFor(handle) );
ALOGD_IF(DEBUG_CONNECTIONS,
- "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%d",
+ "SensorDevice::activate: ident=%p, handle=0x%08x, enabled=%d, count=%zu",
ident, handle, enabled, info.batchParams.size());
if (enabled) {
- ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%d", info.batchParams.indexOfKey(ident));
+ ALOGD_IF(DEBUG_CONNECTIONS, "enable index=%zd", info.batchParams.indexOfKey(ident));
if (info.batchParams.indexOfKey(ident) >= 0) {
if (info.batchParams.size() == 1) {
@@ -150,7 +151,7 @@
ALOGE("\t >>>ERROR: activate called without batch");
}
} else {
- ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%d", info.batchParams.indexOfKey(ident));
+ ALOGD_IF(DEBUG_CONNECTIONS, "disable index=%zd", info.batchParams.indexOfKey(ident));
if (info.removeBatchParamsForIdent(ident) >= 0) {
if (info.batchParams.size() == 0) {
@@ -163,7 +164,7 @@
// batch_rate and timeout. One of the apps has unregistered for sensor
// events, and the best effort batch parameters might have changed.
ALOGD_IF(DEBUG_CONNECTIONS,
- "\t>>> actuating h/w batch %d %d %lld %lld ", handle,
+ "\t>>> actuating h/w batch %d %d %" PRId64 " %" PRId64, handle,
info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
info.bestBatchParams.batchTimeout);
mSensorDevice->batch(mSensorDevice, handle,info.bestBatchParams.flags,
@@ -191,7 +192,7 @@
// On older devices which do not support batch, call setDelay().
if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_1 && info.batchParams.size() > 0) {
- ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %lld ", handle,
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w setDelay %d %" PRId64, handle,
info.bestBatchParams.batchDelay);
mSensorDevice->setDelay(
reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice),
@@ -231,7 +232,7 @@
}
ALOGD_IF(DEBUG_CONNECTIONS,
- "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%lld timeout=%lld",
+ "SensorDevice::batch: ident=%p, handle=0x%08x, flags=%d, period_ns=%" PRId64 " timeout=%" PRId64,
ident, handle, flags, samplingPeriodNs, maxBatchReportLatencyNs);
Mutex::Autolock _l(mLock);
@@ -250,7 +251,8 @@
info.selectBatchParams();
ALOGD_IF(DEBUG_CONNECTIONS,
- "\t>>> curr_period=%lld min_period=%lld curr_timeout=%lld min_timeout=%lld",
+ "\t>>> curr_period=%" PRId64 " min_period=%" PRId64
+ " curr_timeout=%" PRId64 " min_timeout=%" PRId64,
prevBestBatchParams.batchDelay, info.bestBatchParams.batchDelay,
prevBestBatchParams.batchTimeout, info.bestBatchParams.batchTimeout);
@@ -258,7 +260,7 @@
// If the min period or min timeout has changed since the last batch call, call batch.
if (prevBestBatchParams != info.bestBatchParams) {
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_1) {
- ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %lld %lld ", handle,
+ ALOGD_IF(DEBUG_CONNECTIONS, "\t>>> actuating h/w BATCH %d %d %" PRId64 " %" PRId64, handle,
info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
info.bestBatchParams.batchTimeout);
err = mSensorDevice->batch(mSensorDevice, handle, info.bestBatchParams.flags,
@@ -270,7 +272,8 @@
// call setDelay in SensorDevice::activate() method.
}
if (err != NO_ERROR) {
- ALOGE("sensor batch failed %p %d %d %lld %lld err=%s", mSensorDevice, handle,
+ ALOGE("sensor batch failed %p %d %d %" PRId64 " %" PRId64 " err=%s",
+ mSensorDevice, handle,
info.bestBatchParams.flags, info.bestBatchParams.batchDelay,
info.bestBatchParams.batchTimeout, strerror(-err));
info.removeBatchParamsForIdent(ident);
@@ -324,7 +327,7 @@
int64_t maxBatchReportLatencyNs) {
ssize_t index = batchParams.indexOfKey(ident);
if (index < 0) {
- ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%lld timeout=%lld) failed (%s)",
+ ALOGE("Info::setBatchParamsForIdent(ident=%p, period_ns=%" PRId64 " timeout=%" PRId64 ") failed (%s)",
ident, samplingPeriodNs, maxBatchReportLatencyNs, strerror(-index));
return BAD_INDEX;
}
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index 1bee04f..f5dba38 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -223,14 +223,23 @@
s.getHandle(),
s.getRequiredPermission().string());
- if (s.getMinDelay() > 0) {
- result.appendFormat(
- "maxRate=%7.2fHz | ", 1e6f / s.getMinDelay());
+ const int reportingMode = s.getReportingMode();
+ if (reportingMode == AREPORTING_MODE_CONTINUOUS) {
+ result.append("continuous |");
+ } else if (reportingMode == AREPORTING_MODE_ON_CHANGE) {
+ result.append("on-change | ");
+ } else if (reportingMode == AREPORTING_MODE_ONE_SHOT) {
+ result.append("one-shot | ");
} else {
- result.append(s.getMinDelay() == 0
- ? "on-demand | "
- : "one-shot | ");
+ result.append("special-trigger | ");
}
+
+ if (s.getMinDelay() > 0) {
+ result.appendFormat("maxRate=%7.2fHz | ", 1e6f / s.getMinDelay());
+ } else {
+ result.appendFormat("minDelay=%5dus |", s.getMinDelay());
+ }
+
if (s.getFifoMaxEventCount() > 0) {
result.appendFormat("FifoMax=%d events | ",
s.getFifoMaxEventCount());
@@ -301,17 +310,15 @@
void SensorService::cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
sensors_event_t const* buffer, const int count) {
- SensorInterface* sensor;
- status_t err = NO_ERROR;
for (int i=0 ; i<count ; i++) {
int handle = buffer[i].sensor;
- int type = buffer[i].type;
- if (type == SENSOR_TYPE_SIGNIFICANT_MOTION) {
- if (connection->hasSensor(handle)) {
- sensor = mSensorMap.valueFor(handle);
- if (sensor != NULL) {
- sensor->autoDisable(connection.get(), handle);
- }
+ if (connection->hasSensor(handle)) {
+ SensorInterface* sensor = mSensorMap.valueFor(handle);
+ // If this buffer has an event from a one_shot sensor and this connection is registered
+ // for this particular one_shot sensor, try cleaning up the connection.
+ if (sensor != NULL &&
+ sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
+ sensor->autoDisable(connection.get(), handle);
cleanupWithoutDisableLocked(connection, handle);
}
}
@@ -378,7 +385,7 @@
for (size_t j=0 ; j<activeVirtualSensorCount ; j++) {
if (count + k >= minBufferSize) {
ALOGE("buffer too small to hold all events: "
- "count=%u, k=%u, size=%u",
+ "count=%zd, k=%zu, size=%zu",
count, k, minBufferSize);
break;
}
@@ -522,11 +529,11 @@
Mutex::Autolock _l(mLock);
const wp<SensorEventConnection> connection(c);
size_t size = mActiveSensors.size();
- ALOGD_IF(DEBUG_CONNECTIONS, "%d active sensors", size);
+ ALOGD_IF(DEBUG_CONNECTIONS, "%zu active sensors", size);
for (size_t i=0 ; i<size ; ) {
int handle = mActiveSensors.keyAt(i);
if (c->hasSensor(handle)) {
- ALOGD_IF(DEBUG_CONNECTIONS, "%i: disabling handle=0x%08x", i, handle);
+ ALOGD_IF(DEBUG_CONNECTIONS, "%zu: disabling handle=0x%08x", i, handle);
SensorInterface* sensor = mSensorMap.valueFor( handle );
ALOGE_IF(!sensor, "mSensorMap[handle=0x%08x] is null!", handle);
if (sensor) {
@@ -534,9 +541,9 @@
}
}
SensorRecord* rec = mActiveSensors.valueAt(i);
- ALOGE_IF(!rec, "mActiveSensors[%d] is null (handle=0x%08x)!", i, handle);
+ ALOGE_IF(!rec, "mActiveSensors[%zu] is null (handle=0x%08x)!", i, handle);
ALOGD_IF(DEBUG_CONNECTIONS,
- "removing connection %p for sensor[%d].handle=0x%08x",
+ "removing connection %p for sensor[%zu].handle=0x%08x",
c, i, handle);
if (rec && rec->removeConnection(connection)) {
@@ -588,7 +595,7 @@
// this sensor is already activated, but we are adding a connection that uses it.
// Immediately send down the last known value of the requested sensor if it's not a
// "continuous" sensor.
- if (sensor->getSensor().getMinDelay() == 0) {
+ if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ON_CHANGE) {
// NOTE: The wake_up flag of this event may get set to
// WAKE_UP_SENSOR_EVENT_NEEDS_ACK if this is a wake_up event.
sensors_event_t& event(mLastEventSeen.editValueFor(handle));
@@ -625,7 +632,7 @@
samplingPeriodNs = minDelayNs;
}
- ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%lld timeout== %lld",
+ ALOGD_IF(DEBUG_CONNECTIONS, "Calling batch handle==%d flags=%d rate=%" PRId64 " timeout== %" PRId64,
handle, reservedFlags, samplingPeriodNs, maxBatchReportLatencyNs);
status_t err = sensor->batch(connection.get(), handle, reservedFlags, samplingPeriodNs,
@@ -732,8 +739,8 @@
return BAD_VALUE;
}
- if (sensor->getSensor().getType() == SENSOR_TYPE_SIGNIFICANT_MOTION) {
- ALOGE("flush called on Significant Motion sensor");
+ if (sensor->getSensor().getReportingMode() == AREPORTING_MODE_ONE_SHOT) {
+ ALOGE("flush called on a one-shot sensor");
return INVALID_OPERATION;
}
return sensor->flush(connection.get(), handle);
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 0834c80..56c539f 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -37,9 +37,6 @@
LOCAL_CFLAGS:= -DLOG_TAG=\"SurfaceFlinger\"
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
-ifeq ($(TARGET_BOARD_PLATFORM),omap3)
- LOCAL_CFLAGS += -DNO_RGBX_8888
-endif
ifeq ($(TARGET_BOARD_PLATFORM),omap4)
LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
endif
diff --git a/services/surfaceflinger/DispSync.cpp b/services/surfaceflinger/DispSync.cpp
index d771e2c..12da9a5 100644
--- a/services/surfaceflinger/DispSync.cpp
+++ b/services/surfaceflinger/DispSync.cpp
@@ -37,34 +37,23 @@
// Setting this to true enables verbose tracing that can be used to debug
// vsync event model or phase issues.
-static const bool traceDetailedInfo = false;
+static const bool kTraceDetailedInfo = false;
// This is the threshold used to determine when hardware vsync events are
// needed to re-synchronize the software vsync model with the hardware. The
// error metric used is the mean of the squared difference between each
// present time and the nearest software-predicted vsync.
-static const nsecs_t errorThreshold = 160000000000;
-
-// This works around the lack of support for the sync framework on some
-// devices.
-#ifdef RUNNING_WITHOUT_SYNC_FRAMEWORK
-static const bool runningWithoutSyncFramework = true;
-#else
-static const bool runningWithoutSyncFramework = false;
-#endif
+static const nsecs_t kErrorThreshold = 160000000000; // 400 usec squared
// This is the offset from the present fence timestamps to the corresponding
// vsync event.
-static const int64_t presentTimeOffset = PRESENT_TIME_OFFSET_FROM_VSYNC_NS;
+static const int64_t kPresentTimeOffset = PRESENT_TIME_OFFSET_FROM_VSYNC_NS;
class DispSyncThread: public Thread {
public:
DispSyncThread():
- mLowPowerMode(false),
mStop(false),
- mLastVsyncSent(false),
- mLastBufferFull(false),
mPeriod(0),
mPhase(0),
mWakeupLatency(0) {
@@ -138,7 +127,7 @@
// Don't correct by more than 500 us
mWakeupLatency = 500000;
}
- if (traceDetailedInfo) {
+ if (kTraceDetailedInfo) {
ATRACE_INT64("DispSync:WakeupLat", now - nextEventTime);
ATRACE_INT64("DispSync:AvgWakeupLat", mWakeupLatency);
}
@@ -148,18 +137,7 @@
}
if (callbackInvocations.size() > 0) {
- if (mLowPowerMode) {
- if (!mLastVsyncSent || !mLastBufferFull) {
- fireCallbackInvocations(callbackInvocations);
- mLastVsyncSent = true;
- } else
- mLastVsyncSent = false;
- } else {
- fireCallbackInvocations(callbackInvocations);
- }
- mLastBufferFull = true;
- } else {
- mLastBufferFull = false;
+ fireCallbackInvocations(callbackInvocations);
}
}
@@ -207,14 +185,12 @@
return BAD_VALUE;
}
- // This method is only here to handle the runningWithoutSyncFramework
- // case.
+ // This method is only here to handle the kIgnorePresentFences case.
bool hasAnyEventListeners() {
Mutex::Autolock lock(mMutex);
return !mEventListeners.empty();
}
- bool mLowPowerMode;
private:
struct EventListener {
@@ -287,8 +263,6 @@
}
bool mStop;
- bool mLastVsyncSent;
- bool mLastBufferFull;
nsecs_t mPeriod;
nsecs_t mPhase;
@@ -313,19 +287,22 @@
bool mParity;
};
-DispSync::DispSync() {
- mThread = new DispSyncThread();
+DispSync::DispSync() :
+ mRefreshSkipCount(0),
+ mThread(new DispSyncThread()) {
+
mThread->run("DispSync", PRIORITY_URGENT_DISPLAY + PRIORITY_MORE_FAVORABLE);
reset();
beginResync();
- if (traceDetailedInfo) {
- // If runningWithoutSyncFramework is true then the ZeroPhaseTracer
+ if (kTraceDetailedInfo) {
+ // If we're not getting present fences then the ZeroPhaseTracer
// would prevent HW vsync event from ever being turned off.
- // Furthermore the zero-phase tracing is not needed because any time
- // there is an event registered we will turn on the HW vsync events.
- if (!runningWithoutSyncFramework) {
+ // Even if we're just ignoring the fences, the zero-phase tracing is
+ // not needed because any time there is an event registered we will
+ // turn on the HW vsync events.
+ if (!kIgnorePresentFences) {
addEventListener(0, new ZeroPhaseTracer());
}
}
@@ -356,14 +333,14 @@
nsecs_t t = f->getSignalTime();
if (t < INT64_MAX) {
mPresentFences[i].clear();
- mPresentTimes[i] = t + presentTimeOffset;
+ mPresentTimes[i] = t + kPresentTimeOffset;
}
}
}
updateErrorLocked();
- return mPeriod == 0 || mError > errorThreshold;
+ return mPeriod == 0 || mError > kErrorThreshold;
}
void DispSync::beginResync() {
@@ -390,7 +367,7 @@
resetErrorLocked();
}
- if (runningWithoutSyncFramework) {
+ if (kIgnorePresentFences) {
// If we don't have the sync framework we will never have
// addPresentFence called. This means we have no way to know whether
// or not we're synchronized with the HW vsyncs, so we just request
@@ -399,7 +376,7 @@
return mThread->hasAnyEventListeners();
}
- return mPeriod == 0 || mError > errorThreshold;
+ return mPeriod == 0 || mError > kErrorThreshold;
}
void DispSync::endResync() {
@@ -412,8 +389,11 @@
return mThread->addEventListener(phase, callback);
}
-void DispSync::setLowPowerMode(bool enabled) {
- mThread->mLowPowerMode = enabled;
+void DispSync::setRefreshSkipCount(int count) {
+ Mutex::Autolock lock(mMutex);
+ ALOGD("setRefreshSkipCount(%d)", count);
+ mRefreshSkipCount = count;
+ updateModelLocked();
}
status_t DispSync::removeEventListener(const sp<Callback>& callback) {
@@ -459,11 +439,14 @@
mPhase += mPeriod;
}
- if (traceDetailedInfo) {
+ if (kTraceDetailedInfo) {
ATRACE_INT64("DispSync:Period", mPeriod);
ATRACE_INT64("DispSync:Phase", mPhase);
}
+ // Artificially inflate the period if requested.
+ mPeriod += mPeriod * mRefreshSkipCount;
+
mThread->updateModel(mPeriod, mPhase);
}
}
@@ -473,15 +456,19 @@
return;
}
+ // Need to compare present fences against the un-adjusted refresh period,
+ // since they might arrive between two events.
+ nsecs_t period = mPeriod / (1 + mRefreshSkipCount);
+
int numErrSamples = 0;
nsecs_t sqErrSum = 0;
for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) {
nsecs_t sample = mPresentTimes[i];
if (sample > mPhase) {
- nsecs_t sampleErr = (sample - mPhase) % mPeriod;
- if (sampleErr > mPeriod / 2) {
- sampleErr -= mPeriod;
+ nsecs_t sampleErr = (sample - mPhase) % period;
+ if (sampleErr > period / 2) {
+ sampleErr -= period;
}
sqErrSum += sampleErr * sampleErr;
numErrSamples++;
@@ -494,7 +481,7 @@
mError = 0;
}
- if (traceDetailedInfo) {
+ if (kTraceDetailedInfo) {
ATRACE_INT64("DispSync:Error", mError);
}
}
@@ -516,13 +503,16 @@
void DispSync::dump(String8& result) const {
Mutex::Autolock lock(mMutex);
- result.appendFormat("mPeriod: %"PRId64" ns\n", mPeriod);
- result.appendFormat("mPhase: %"PRId64" ns\n", mPhase);
- result.appendFormat("mError: %"PRId64" ns (sqrt: %.1f)\n",
+ result.appendFormat("present fences are %s\n",
+ kIgnorePresentFences ? "ignored" : "used");
+ result.appendFormat("mPeriod: %" PRId64 " ns (%.3f fps; skipCount=%d)\n",
+ mPeriod, 1000000000.0 / mPeriod, mRefreshSkipCount);
+ result.appendFormat("mPhase: %" PRId64 " ns\n", mPhase);
+ result.appendFormat("mError: %" PRId64 " ns (sqrt=%.1f)\n",
mError, sqrt(mError));
- result.appendFormat("mNumResyncSamplesSincePresent: %d (max %d)\n",
+ result.appendFormat("mNumResyncSamplesSincePresent: %d (limit %d)\n",
mNumResyncSamplesSincePresent, MAX_RESYNC_SAMPLES_WITHOUT_PRESENT);
- result.appendFormat("mNumResyncSamples: %d (max %d)\n",
+ result.appendFormat("mNumResyncSamples: %zd (max %d)\n",
mNumResyncSamples, MAX_RESYNC_SAMPLES);
result.appendFormat("mResyncSamples:\n");
@@ -531,9 +521,9 @@
size_t idx = (mFirstResyncSample + i) % MAX_RESYNC_SAMPLES;
nsecs_t sampleTime = mResyncSamples[idx];
if (i == 0) {
- result.appendFormat(" %"PRId64"\n", sampleTime);
+ result.appendFormat(" %" PRId64 "\n", sampleTime);
} else {
- result.appendFormat(" %"PRId64" (+%"PRId64")\n",
+ result.appendFormat(" %" PRId64 " (+%" PRId64 ")\n",
sampleTime, sampleTime - previous);
}
previous = sampleTime;
@@ -541,6 +531,7 @@
result.appendFormat("mPresentFences / mPresentTimes [%d]:\n",
NUM_PRESENT_SAMPLES);
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
previous = 0;
for (size_t i = 0; i < NUM_PRESENT_SAMPLES; i++) {
size_t idx = (i + mPresentSampleOffset) % NUM_PRESENT_SAMPLES;
@@ -548,15 +539,21 @@
nsecs_t presentTime = mPresentTimes[idx];
if (!signaled) {
result.appendFormat(" [unsignaled fence]\n");
+ } else if (presentTime == 0) {
+ result.appendFormat(" 0\n");
} else if (previous == 0) {
- result.appendFormat(" %"PRId64"\n", presentTime);
+ result.appendFormat(" %" PRId64 " (%.3f ms ago)\n", presentTime,
+ (now - presentTime) / 1000000.0);
} else {
- result.appendFormat(" %"PRId64" (+%"PRId64" / %.3f)\n",
+ result.appendFormat(" %" PRId64 " (+%" PRId64 " / %.3f) (%.3f ms ago)\n",
presentTime, presentTime - previous,
- (presentTime - previous) / (double) mPeriod);
+ (presentTime - previous) / (double) mPeriod,
+ (now - presentTime) / 1000000.0);
}
previous = presentTime;
}
+
+ result.appendFormat("current monotonic time: %" PRId64 "\n", now);
}
} // namespace android
diff --git a/services/surfaceflinger/DispSync.h b/services/surfaceflinger/DispSync.h
index a33ce5d..7a26df3 100644
--- a/services/surfaceflinger/DispSync.h
+++ b/services/surfaceflinger/DispSync.h
@@ -25,6 +25,18 @@
namespace android {
+// Ignore present (retire) fences if the device doesn't have support for the
+// sync framework, or if all phase offsets are zero. The latter is useful
+// because it allows us to avoid resync bursts on devices that don't need
+// phase-offset VSYNC events.
+#if defined(RUNNING_WITHOUT_SYNC_FRAMEWORK) || \
+ (VSYNC_EVENT_PHASE_OFFSET_NS == 0 && SF_VSYNC_EVENT_PHASE_OFFSET_NS == 0)
+static const bool kIgnorePresentFences = true;
+#else
+static const bool kIgnorePresentFences = false;
+#endif
+
+
class String8;
class Fence;
class DispSyncThread;
@@ -55,6 +67,7 @@
DispSync();
~DispSync();
+ // reset clears the resync samples and error value.
void reset();
// addPresentFence adds a fence for use in validating the current vsync
@@ -88,8 +101,11 @@
// turned on. It should NOT be used after that.
void setPeriod(nsecs_t period);
- // Setting the low power mode reduces the frame rate to half of the default
- void setLowPowerMode(bool enabled);
+ // setRefreshSkipCount specifies an additional number of refresh
+ // cycles to skip. For example, on a 60Hz display, a skip count of 1
+ // will result in events happening at 30Hz. Default is zero. The idea
+ // is to sacrifice smoothness for battery life.
+ void setRefreshSkipCount(int count);
// addEventListener registers a callback to be called repeatedly at the
// given phase offset from the hardware vsync events. The callback is
@@ -149,6 +165,8 @@
nsecs_t mPresentTimes[NUM_PRESENT_SAMPLES];
size_t mPresentSampleOffset;
+ int mRefreshSkipCount;
+
// mThread is the thread from which all the callbacks are called.
sp<DispSyncThread> mThread;
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 4ebe291..71377ed 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -70,9 +70,9 @@
mPageFlipCount(),
mIsSecure(isSecure),
mSecureLayerVisible(false),
- mScreenAcquired(false),
mLayerStack(NO_LAYER_STACK),
- mOrientation()
+ mOrientation(),
+ mPowerMode(HWC_POWER_MODE_OFF)
{
mNativeWindow = new Surface(producer, false);
ANativeWindow* const window = mNativeWindow.get();
@@ -109,7 +109,8 @@
mFrame.makeInvalid();
// virtual displays are always considered enabled
- mScreenAcquired = (mType >= DisplayDevice::DISPLAY_VIRTUAL);
+ mPowerMode = (mType >= DisplayDevice::DISPLAY_VIRTUAL) ?
+ HWC_POWER_MODE_NORMAL : HWC_POWER_MODE_OFF;
// Name the display. The name will be replaced shortly if the display
// was created with createDisplay().
@@ -322,21 +323,16 @@
}
// ----------------------------------------------------------------------------
-
-bool DisplayDevice::canDraw() const {
- return mScreenAcquired;
+void DisplayDevice::setPowerMode(int mode) {
+ mPowerMode = mode;
}
-void DisplayDevice::releaseScreen() const {
- mScreenAcquired = false;
+int DisplayDevice::getPowerMode() const {
+ return mPowerMode;
}
-void DisplayDevice::acquireScreen() const {
- mScreenAcquired = true;
-}
-
-bool DisplayDevice::isScreenAcquired() const {
- return mScreenAcquired;
+bool DisplayDevice::isDisplayOn() const {
+ return (mPowerMode != HWC_POWER_MODE_OFF);
}
// ----------------------------------------------------------------------------
@@ -465,13 +461,13 @@
result.appendFormat(
"+ DisplayDevice: %s\n"
" type=%x, hwcId=%d, layerStack=%u, (%4dx%4d), ANativeWindow=%p, orient=%2d (type=%08x), "
- "flips=%u, isSecure=%d, secureVis=%d, acquired=%d, numLayers=%zu\n"
+ "flips=%u, isSecure=%d, secureVis=%d, powerMode=%d, numLayers=%zu\n"
" v:[%d,%d,%d,%d], f:[%d,%d,%d,%d], s:[%d,%d,%d,%d],"
"transform:[[%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f][%0.3f,%0.3f,%0.3f]]\n",
mDisplayName.string(), mType, mHwcDisplayId,
mLayerStack, mDisplayWidth, mDisplayHeight, mNativeWindow.get(),
mOrientation, tr.getType(), getPageFlipCount(),
- mIsSecure, mSecureLayerVisible, mScreenAcquired, mVisibleLayersSortedByZ.size(),
+ mIsSecure, mSecureLayerVisible, mPowerMode, mVisibleLayersSortedByZ.size(),
mViewport.left, mViewport.top, mViewport.right, mViewport.bottom,
mFrame.left, mFrame.top, mFrame.right, mFrame.bottom,
mScissor.left, mScissor.top, mScissor.right, mScissor.bottom,
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index f750c6c..4c8ef02 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -147,12 +147,11 @@
void setViewportAndProjection() const;
/* ------------------------------------------------------------------------
- * blank / unblank management
+ * Display power mode management.
*/
- void releaseScreen() const;
- void acquireScreen() const;
- bool isScreenAcquired() const;
- bool canDraw() const;
+ int getPowerMode() const;
+ void setPowerMode(int mode);
+ bool isDisplayOn() const;
// release HWC resources (if any) for removable displays
void disconnect(HWComposer& hwc);
@@ -197,9 +196,6 @@
// Whether we have a visible secure layer on this display
bool mSecureLayerVisible;
- // Whether the screen is blanked;
- mutable int mScreenAcquired;
-
/*
* Transaction state
@@ -217,6 +213,8 @@
Rect mScissor;
Transform mGlobalTransform;
bool mNeedsFiltering;
+ // Current power mode
+ int mPowerMode;
};
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index c3b2159..185dab2 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -759,19 +759,18 @@
return (status_t)err;
}
-status_t HWComposer::release(int disp) {
+status_t HWComposer::setPowerMode(int disp, int mode) {
LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
if (mHwc) {
- eventControl(disp, HWC_EVENT_VSYNC, 0);
- return (status_t)mHwc->blank(mHwc, disp, 1);
- }
- return NO_ERROR;
-}
-
-status_t HWComposer::acquire(int disp) {
- LOG_FATAL_IF(disp >= VIRTUAL_DISPLAY_ID_BASE);
- if (mHwc) {
- return (status_t)mHwc->blank(mHwc, disp, 0);
+ if (mode == HWC_POWER_MODE_OFF) {
+ eventControl(disp, HWC_EVENT_VSYNC, 0);
+ }
+ if (hwcHasApiVersion(mHwc, HWC_DEVICE_API_VERSION_1_4)) {
+ return (status_t)mHwc->setPowerMode(mHwc, disp, mode);
+ } else {
+ return (status_t)mHwc->blank(mHwc, disp,
+ mode == HWC_POWER_MODE_OFF ? 1 : 0);
+ }
}
return NO_ERROR;
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 2f92672..c62b924 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -97,11 +97,8 @@
// commits the list
status_t commit();
- // release hardware resources and blank screen
- status_t release(int disp);
-
- // acquire hardware resources and unblank screen
- status_t acquire(int disp);
+ // set power mode
+ status_t setPowerMode(int disp, int mode);
// reset state when an external, non-virtual display is disconnected
void disconnectDisplay(int disp);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index cd5fe6b..4238ef8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -88,14 +88,6 @@
namespace android {
-// This works around the lack of support for the sync framework on some
-// devices.
-#ifdef RUNNING_WITHOUT_SYNC_FRAMEWORK
-static const bool runningWithoutSyncFramework = true;
-#else
-static const bool runningWithoutSyncFramework = false;
-#endif
-
// This is the phase offset in nanoseconds of the software vsync event
// relative to the vsync event reported by HWComposer. The software vsync
// event is when SurfaceFlinger and Choreographer-based applications run each
@@ -322,10 +314,13 @@
class DispSyncSource : public VSyncSource, private DispSync::Callback {
public:
- DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync) :
+ DispSyncSource(DispSync* dispSync, nsecs_t phaseOffset, bool traceVsync,
+ const char* label) :
mValue(0),
mPhaseOffset(phaseOffset),
mTraceVsync(traceVsync),
+ mVsyncOnLabel(String8::format("VsyncOn-%s", label)),
+ mVsyncEventLabel(String8::format("VSYNC-%s", label)),
mDispSync(dispSync) {}
virtual ~DispSyncSource() {}
@@ -340,7 +335,7 @@
ALOGE("error registering vsync callback: %s (%d)",
strerror(-err), err);
}
- ATRACE_INT("VsyncOn", 1);
+ //ATRACE_INT(mVsyncOnLabel.string(), 1);
} else {
status_t err = mDispSync->removeEventListener(
static_cast<DispSync::Callback*>(this));
@@ -348,7 +343,7 @@
ALOGE("error unregistering vsync callback: %s (%d)",
strerror(-err), err);
}
- ATRACE_INT("VsyncOn", 0);
+ //ATRACE_INT(mVsyncOnLabel.string(), 0);
}
}
@@ -366,7 +361,7 @@
if (mTraceVsync) {
mValue = (mValue + 1) % 2;
- ATRACE_INT("VSYNC", mValue);
+ ATRACE_INT(mVsyncEventLabel.string(), mValue);
}
}
@@ -379,6 +374,8 @@
const nsecs_t mPhaseOffset;
const bool mTraceVsync;
+ const String8 mVsyncOnLabel;
+ const String8 mVsyncEventLabel;
DispSync* mDispSync;
sp<VSyncSource::Callback> mCallback;
@@ -437,7 +434,7 @@
// for displays other than the main display, so we always
// assume a connected display is unblanked.
ALOGD("marking display %zu as acquired/unblanked", i);
- hw->acquireScreen();
+ hw->setPowerMode(HWC_POWER_MODE_NORMAL);
}
mDisplays.add(token, hw);
}
@@ -449,10 +446,10 @@
// start the EventThread
sp<VSyncSource> vsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- vsyncPhaseOffsetNs, true);
+ vsyncPhaseOffsetNs, true, "app");
mEventThread = new EventThread(vsyncSrc);
sp<VSyncSource> sfVsyncSrc = new DispSyncSource(&mPrimaryDispSync,
- sfVsyncPhaseOffsetNs, false);
+ sfVsyncPhaseOffsetNs, true, "sf");
mSFEventThread = new EventThread(sfVsyncSrc);
mEventQueue.setEventThread(mSFEventThread);
@@ -579,6 +576,22 @@
info.xdpi = xdpi;
info.ydpi = ydpi;
info.fps = float(1e9 / hwConfig.refresh);
+ info.appVsyncOffset = VSYNC_EVENT_PHASE_OFFSET_NS;
+
+ // This is how far in advance a buffer must be queued for
+ // presentation at a given time. If you want a buffer to appear
+ // on the screen at time N, you must submit the buffer before
+ // (N - presentationDeadline).
+ //
+ // Normally it's one full refresh period (to give SF a chance to
+ // latch the buffer), but this can be reduced by configuring a
+ // DispSync offset. Any additional delays introduced by the hardware
+ // composer or panel must be accounted for here.
+ //
+ // We add an additional 1ms to allow for processing time and
+ // differences between the ideal and actual refresh rate.
+ info.presentationDeadline =
+ hwConfig.refresh - SF_VSYNC_EVENT_PHASE_OFFSET_NS + 1000000;
// All non-virtual displays are currently considered secure.
info.secure = true;
@@ -589,11 +602,11 @@
return NO_ERROR;
}
-int SurfaceFlinger::getActiveConfig(const sp<IBinder>& display) {
+int SurfaceFlinger::getActiveConfig(const sp<IBinder>&) {
return 0;
}
-status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>& display, int id) {
+status_t SurfaceFlinger::setActiveConfig(const sp<IBinder>&, int) {
return NO_ERROR;
}
@@ -793,7 +806,7 @@
const bool repaintEverything = mRepaintEverything;
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
const sp<DisplayDevice>& hw(mDisplays[dpy]);
- if (hw->canDraw()) {
+ if (hw->isDisplayOn()) {
// transform the dirty region into this screen's coordinate space
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
if (!dirtyRegion.isEmpty()) {
@@ -858,9 +871,9 @@
}
}
- if (runningWithoutSyncFramework) {
+ if (kIgnorePresentFences) {
const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
- if (hw->isScreenAcquired()) {
+ if (hw->isDisplayOn()) {
enableHardwareVsync();
}
}
@@ -895,7 +908,7 @@
const sp<DisplayDevice>& hw(mDisplays[dpy]);
const Transform& tr(hw->getTransform());
const Rect bounds(hw->getBounds());
- if (hw->canDraw()) {
+ if (hw->isDisplayOn()) {
SurfaceFlinger::computeVisibleRegions(layers,
hw->getLayerStack(), dirtyRegion, opaqueRegion);
@@ -991,7 +1004,7 @@
const bool repaintEverything = android_atomic_and(0, &mRepaintEverything);
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
const sp<DisplayDevice>& hw(mDisplays[dpy]);
- if (hw->canDraw()) {
+ if (hw->isDisplayOn()) {
// transform the dirty region into this screen's coordinate space
const Region dirtyRegion(hw->getDirtyRegion(repaintEverything));
@@ -2005,19 +2018,10 @@
format = PIXEL_FORMAT_RGBA_8888;
break;
case PIXEL_FORMAT_OPAQUE:
-#ifdef NO_RGBX_8888
- format = PIXEL_FORMAT_RGB_565;
-#else
format = PIXEL_FORMAT_RGBX_8888;
-#endif
break;
}
-#ifdef NO_RGBX_8888
- if (format == PIXEL_FORMAT_RGBX_8888)
- format = PIXEL_FORMAT_RGBA_8888;
-#endif
-
*outLayer = new Layer(this, client, name, w, h, flags);
status_t err = (*outLayer)->setBuffers(w, h, format, flags);
if (err == NO_ERROR) {
@@ -2082,7 +2086,7 @@
d.viewport.makeInvalid();
displays.add(d);
setTransactionState(state, displays, 0);
- onScreenAcquired(getDefaultDisplayDevice());
+ setPowerModeInternal(getDisplayDevice(d.token), HWC_POWER_MODE_NORMAL);
const nsecs_t period =
getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY);
@@ -2103,42 +2107,35 @@
postMessageAsync(msg); // we may be called from main thread, use async message
}
+void SurfaceFlinger::setPowerModeInternal(const sp<DisplayDevice>& hw,
+ int mode) {
+ ALOGD("Set power mode=%d, type=%d flinger=%p", mode, hw->getDisplayType(),
+ this);
+ int32_t type = hw->getDisplayType();
+ int currentMode = hw->getPowerMode();
-void SurfaceFlinger::onScreenAcquired(const sp<const DisplayDevice>& hw) {
- ALOGD("Screen acquired, type=%d flinger=%p", hw->getDisplayType(), this);
- if (hw->isScreenAcquired()) {
- // this is expected, e.g. when power manager wakes up during boot
- ALOGD(" screen was previously acquired");
+ if (mode == currentMode) {
+ ALOGD("Screen type=%d is already mode=%d", hw->getDisplayType(), mode);
return;
}
- hw->acquireScreen();
- int32_t type = hw->getDisplayType();
- if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
- // built-in display, tell the HWC
- getHwComposer().acquire(type);
+ hw->setPowerMode(mode);
+ if (type >= DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
+ ALOGW("Trying to set power mode for virtual display");
+ return;
+ }
+ if (currentMode == HWC_POWER_MODE_OFF) {
+ getHwComposer().setPowerMode(type, mode);
if (type == DisplayDevice::DISPLAY_PRIMARY) {
// FIXME: eventthread only knows about the main display right now
mEventThread->onScreenAcquired();
-
resyncToHardwareVsync(true);
}
- }
- mVisibleRegionsDirty = true;
- repaintEverything();
-}
-void SurfaceFlinger::onScreenReleased(const sp<const DisplayDevice>& hw) {
- ALOGD("Screen released, type=%d flinger=%p", hw->getDisplayType(), this);
- if (!hw->isScreenAcquired()) {
- ALOGD(" screen was previously released");
- return;
- }
-
- hw->releaseScreen();
- int32_t type = hw->getDisplayType();
- if (type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES) {
+ mVisibleRegionsDirty = true;
+ repaintEverything();
+ } else if (mode == HWC_POWER_MODE_OFF) {
if (type == DisplayDevice::DISPLAY_PRIMARY) {
disableHardwareVsync(true); // also cancels any in-progress resync
@@ -2146,56 +2143,38 @@
mEventThread->onScreenReleased();
}
- // built-in display, tell the HWC
- getHwComposer().release(type);
+ getHwComposer().setPowerMode(type, mode);
+ mVisibleRegionsDirty = true;
+ // from this point on, SF will stop drawing on this display
+ } else {
+ getHwComposer().setPowerMode(type, mode);
}
- mVisibleRegionsDirty = true;
- // from this point on, SF will stop drawing on this display
}
-void SurfaceFlinger::unblank(const sp<IBinder>& display) {
- class MessageScreenAcquired : public MessageBase {
+void SurfaceFlinger::setPowerMode(const sp<IBinder>& display, int mode) {
+ class MessageSetPowerMode: public MessageBase {
SurfaceFlinger& mFlinger;
sp<IBinder> mDisplay;
+ int mMode;
public:
- MessageScreenAcquired(SurfaceFlinger& flinger,
- const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { }
+ MessageSetPowerMode(SurfaceFlinger& flinger,
+ const sp<IBinder>& disp, int mode) : mFlinger(flinger),
+ mDisplay(disp) { mMode = mode; }
virtual bool handler() {
- const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
+ sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
if (hw == NULL) {
- ALOGE("Attempt to unblank null display %p", mDisplay.get());
+ ALOGE("Attempt to set power mode = %d for null display %p",
+ mDisplay.get(), mMode);
} else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
- ALOGW("Attempt to unblank virtual display");
+ ALOGW("Attempt to set power mode = %d for virtual display",
+ mMode);
} else {
- mFlinger.onScreenAcquired(hw);
+ mFlinger.setPowerModeInternal(hw, mMode);
}
return true;
}
};
- sp<MessageBase> msg = new MessageScreenAcquired(*this, display);
- postMessageSync(msg);
-}
-
-void SurfaceFlinger::blank(const sp<IBinder>& display) {
- class MessageScreenReleased : public MessageBase {
- SurfaceFlinger& mFlinger;
- sp<IBinder> mDisplay;
- public:
- MessageScreenReleased(SurfaceFlinger& flinger,
- const sp<IBinder>& disp) : mFlinger(flinger), mDisplay(disp) { }
- virtual bool handler() {
- const sp<DisplayDevice> hw(mFlinger.getDisplayDevice(mDisplay));
- if (hw == NULL) {
- ALOGE("Attempt to blank null display %p", mDisplay.get());
- } else if (hw->getDisplayType() >= DisplayDevice::DISPLAY_VIRTUAL) {
- ALOGW("Attempt to blank virtual display");
- } else {
- mFlinger.onScreenReleased(hw);
- }
- return true;
- }
- };
- sp<MessageBase> msg = new MessageScreenReleased(*this, display);
+ sp<MessageBase> msg = new MessageSetPowerMode(*this, display, mode);
postMessageSync(msg);
}
@@ -2348,9 +2327,6 @@
{
static const char* config =
" [sf"
-#ifdef NO_RGBX_8888
- " NO_RGBX_8888"
-#endif
#ifdef HAS_CONTEXT_PRIORITY
" HAS_CONTEXT_PRIORITY"
#endif
@@ -2456,8 +2432,8 @@
mRenderEngine->dump(result);
hw->undefinedRegion.dump(result, "undefinedRegion");
- result.appendFormat(" orientation=%d, canDraw=%d\n",
- hw->getOrientation(), hw->canDraw());
+ result.appendFormat(" orientation=%d, isDisplayOn=%d\n",
+ hw->getOrientation(), hw->isDisplayOn());
result.appendFormat(
" last eglSwapBuffers() time: %f us\n"
" last transaction time : %f us\n"
@@ -2549,10 +2525,9 @@
case CREATE_DISPLAY:
case SET_TRANSACTION_STATE:
case BOOT_FINISHED:
- case BLANK:
- case UNBLANK:
case CLEAR_ANIMATION_FRAME_STATS:
case GET_ANIMATION_FRAME_STATS:
+ case SET_POWER_MODE:
{
// codes that require permission check
IPCThreadState* ipc = IPCThreadState::self();
@@ -2685,11 +2660,8 @@
// This is an experimental interface
// Needs to be shifted to proper binder interface when we productize
case 1016: {
- mPrimaryDispSync.setLowPowerMode(true);
- return NO_ERROR;
- }
- case 1017: {
- mPrimaryDispSync.setLowPowerMode(false);
+ n = data.readInt32();
+ mPrimaryDispSync.setRefreshSkipCount(n);
return NO_ERROR;
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index cc01eb3..996a795 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -205,13 +205,10 @@
Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight,
uint32_t minLayerZ, uint32_t maxLayerZ,
bool useIdentityTransform);
- // called when screen needs to turn off
- virtual void blank(const sp<IBinder>& display);
- // called when screen is turning back on
- virtual void unblank(const sp<IBinder>& display);
virtual status_t getDisplayConfigs(const sp<IBinder>& display,
Vector<DisplayInfo>* configs);
virtual int getActiveConfig(const sp<IBinder>& display);
+ virtual void setPowerMode(const sp<IBinder>& display, int mode);
virtual status_t setActiveConfig(const sp<IBinder>& display, int id);
virtual status_t clearAnimationFrameStats();
virtual status_t getAnimationFrameStats(FrameStats* outStats) const;
@@ -242,10 +239,8 @@
// called on the main thread in response to initializeDisplays()
void onInitializeDisplays();
- // called on the main thread in response to blank()
- void onScreenReleased(const sp<const DisplayDevice>& hw);
- // called on the main thread in response to unblank()
- void onScreenAcquired(const sp<const DisplayDevice>& hw);
+ // called on the main thread in response to setPowerMode()
+ void setPowerModeInternal(const sp<DisplayDevice>& hw, int mode);
void handleMessageTransaction();
void handleMessageInvalidate();