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();