Merge "Merge kwd to master"
diff --git a/cmds/installd/utils.c b/cmds/installd/utils.c
index 420ad5e..120fd62 100644
--- a/cmds/installd/utils.c
+++ b/cmds/installd/utils.c
@@ -1036,50 +1036,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 1e6549f..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
@@ -82,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;
}
@@ -161,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;
@@ -171,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;
@@ -241,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:
@@ -255,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;
@@ -280,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;
@@ -295,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/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/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/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/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 9111dbb..edf867a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -434,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);
}
@@ -790,7 +790,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()) {
@@ -857,7 +857,7 @@
if (kIgnorePresentFences) {
const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
- if (hw->isScreenAcquired()) {
+ if (hw->isDisplayOn()) {
enableHardwareVsync();
}
}
@@ -892,7 +892,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);
@@ -988,7 +988,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));
@@ -2070,7 +2070,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);
@@ -2091,42 +2091,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
@@ -2134,56 +2127,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);
}
@@ -2441,8 +2416,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"
@@ -2534,10 +2509,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();
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();