Merge "omx: add DescribeColorAspectsParams param"
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index c043adc..7562ac8 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -578,8 +578,8 @@
         fprintf(stderr, "send_broadcast: too many arguments (%d)\n", (int) args.size());
         return;
     }
-    const char *am_args[1024] = { "/system/bin/am", "broadcast", "--user", "0",
-                                  "-a", action.c_str() };
+    const char *am_args[1024] = { "/system/bin/am", "broadcast", "--receiver-foreground",
+                                  "--user", "0", "-a", action.c_str() };
     size_t am_index = 5; // Starts at the index of last initial value above.
     for (const std::string& arg : args) {
         am_args[++am_index] = arg.c_str();
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index fad5ce6..f25060c 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -598,7 +598,7 @@
     return strcmp(tmp_property_value, "true") == 0;
 }
 
-static void run_dex2oat(int zip_fd, int oat_fd, const char* input_file_name,
+static void run_dex2oat(int zip_fd, int oat_fd, int image_fd, const char* input_file_name,
     const char* output_file_name, int swap_fd, const char *instruction_set,
     bool vm_safe_mode, bool debuggable, bool post_bootcomplete, bool extract_only,
     const std::vector<int>& profile_files_fd, const std::vector<int>& reference_profile_files_fd) {
@@ -684,6 +684,8 @@
     char dex2oat_compiler_filter_arg[strlen("--compiler-filter=") + kPropertyValueMax];
     bool have_dex2oat_swap_fd = false;
     char dex2oat_swap_fd[strlen("--swap-fd=") + MAX_INT_LEN];
+    bool have_dex2oat_image_fd = false;
+    char dex2oat_image_fd[strlen("--app-image-fd=") + MAX_INT_LEN];
 
     sprintf(zip_fd_arg, "--zip-fd=%d", zip_fd);
     sprintf(zip_location_arg, "--zip-location=%s", input_file_name);
@@ -696,6 +698,10 @@
         have_dex2oat_swap_fd = true;
         sprintf(dex2oat_swap_fd, "--swap-fd=%d", swap_fd);
     }
+    if (image_fd >= 0) {
+        have_dex2oat_image_fd = true;
+        sprintf(dex2oat_image_fd, "--app-image-fd=%d", image_fd);
+    }
 
     if (have_dex2oat_Xms_flag) {
         sprintf(dex2oat_Xms_arg, "-Xms%s", dex2oat_Xms_flag);
@@ -746,6 +752,7 @@
                      + (have_dex2oat_compiler_filter_flag ? 1 : 0)
                      + (have_dex2oat_threads_flag ? 1 : 0)
                      + (have_dex2oat_swap_fd ? 1 : 0)
+                     + (have_dex2oat_image_fd ? 1 : 0)
                      + (have_dex2oat_relocation_skip_flag ? 2 : 0)
                      + (generate_debug_info ? 1 : 0)
                      + (debuggable ? 1 : 0)
@@ -782,6 +789,9 @@
     if (have_dex2oat_swap_fd) {
         argv[i++] = dex2oat_swap_fd;
     }
+    if (have_dex2oat_image_fd) {
+        argv[i++] = dex2oat_image_fd;
+    }
     if (generate_debug_info) {
         argv[i++] = "--generate-debug-info";
     }
@@ -964,6 +974,37 @@
     }
 }
 
+static void trim_extension(char* path) {
+  // Trim the extension.
+  int pos = strlen(path);
+  for (; pos >= 0 && path[pos] != '.'; --pos) {}
+  if (pos >= 0) {
+      path[pos] = '\0';  // Trim extension
+  }
+}
+
+static int open_with_extension(char* file_name, const char* extension) {
+    if (strlen(file_name) + strlen(extension) + 1 <= PKG_PATH_MAX) {
+        strcat(file_name, extension);
+        unlink(file_name);
+        return open(file_name, O_RDWR | O_CREAT | O_EXCL, 0600);
+    }
+    return -1;
+}
+
+static bool set_permissions_and_ownership(int fd, bool is_public, int uid, const char* path) {
+    if (fchmod(fd,
+               S_IRUSR|S_IWUSR|S_IRGRP |
+               (is_public ? S_IROTH : 0)) < 0) {
+        ALOGE("installd cannot chmod '%s' during dexopt\n", path);
+        return false;
+    } else if (fchown(fd, AID_SYSTEM, uid) < 0) {
+        ALOGE("installd cannot chown '%s' during dexopt\n", path);
+        return false;
+    }
+    return true;
+}
+
 int dexopt(const char* apk_path, uid_t uid, const char* pkgname, const char* instruction_set,
            int dexopt_needed, const char* oat_dir, int dexopt_flags, const char* volume_uuid,
            bool use_profiles)
@@ -972,9 +1013,10 @@
     struct stat input_stat;
     char out_path[PKG_PATH_MAX];
     char swap_file_name[PKG_PATH_MAX];
+    char image_path[PKG_PATH_MAX];
     const char *input_file;
     char in_odex_path[PKG_PATH_MAX];
-    int res, input_fd=-1, out_fd=-1, swap_fd=-1;
+    int res, input_fd=-1, out_fd=-1, image_fd=-1, swap_fd=-1;
     bool is_public = (dexopt_flags & DEXOPT_PUBLIC) != 0;
     bool vm_safe_mode = (dexopt_flags & DEXOPT_SAFEMODE) != 0;
     bool debuggable = (dexopt_flags & DEXOPT_DEBUGGABLE) != 0;
@@ -1053,40 +1095,35 @@
         ALOGE("installd cannot open '%s' for output during dexopt\n", out_path);
         goto fail;
     }
-    if (fchmod(out_fd,
-               S_IRUSR|S_IWUSR|S_IRGRP |
-               (is_public ? S_IROTH : 0)) < 0) {
-        ALOGE("installd cannot chmod '%s' during dexopt\n", out_path);
-        goto fail;
-    }
-    if (fchown(out_fd, AID_SYSTEM, uid) < 0) {
-        ALOGE("installd cannot chown '%s' during dexopt\n", out_path);
+    if (!set_permissions_and_ownership(out_fd, is_public, uid, out_path)) {
         goto fail;
     }
 
     // Create a swap file if necessary.
     if (ShouldUseSwapFileForDexopt()) {
         // Make sure there really is enough space.
-        size_t out_len = strlen(out_path);
-        if (out_len + strlen(".swap") + 1 <= PKG_PATH_MAX) {
-            strcpy(swap_file_name, out_path);
-            strcpy(swap_file_name + strlen(out_path), ".swap");
-            unlink(swap_file_name);
-            swap_fd = open(swap_file_name, O_RDWR | O_CREAT | O_EXCL, 0600);
-            if (swap_fd < 0) {
-                // Could not create swap file. Optimistically go on and hope that we can compile
-                // without it.
-                ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name);
-            } else {
-                // Immediately unlink. We don't really want to hit flash.
-                unlink(swap_file_name);
-            }
+        strcpy(swap_file_name, out_path);
+        swap_fd = open_with_extension(swap_file_name, ".swap");
+        if (swap_fd < 0) {
+            // Could not create swap file. Optimistically go on and hope that we can compile
+            // without it.
+            ALOGE("installd could not create '%s' for swap during dexopt\n", swap_file_name);
         } else {
-            // Swap file path is too long. Try to run without.
-            ALOGE("installd could not create swap file for path %s during dexopt\n", out_path);
+            // Immediately unlink. We don't really want to hit flash.
+            unlink(swap_file_name);
         }
     }
 
+    strcpy(image_path, out_path);
+    trim_extension(image_path);
+    image_fd = open_with_extension(image_path, ".art");
+    if (image_fd < 0) {
+        // Could not create swap file. Optimistically go on and hope that we can compile
+        // without it.
+        ALOGE("installd could not create '%s' for image file during dexopt\n", image_path);
+    } else if (!set_permissions_and_ownership(image_fd, is_public, uid, image_path)) {
+        image_fd = -1;
+    }
     ALOGV("DexInv: --- BEGIN '%s' ---\n", input_file);
 
     pid_t pid;
@@ -1121,7 +1158,7 @@
             || dexopt_needed == DEXOPT_SELF_PATCHOAT_NEEDED) {
             run_patchoat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set);
         } else if (dexopt_needed == DEXOPT_DEX2OAT_NEEDED) {
-            run_dex2oat(input_fd, out_fd, input_file, out_path, swap_fd,
+            run_dex2oat(input_fd, out_fd, image_fd, input_file, out_path, swap_fd,
                         instruction_set, vm_safe_mode, debuggable, boot_complete, extract_only,
                         profile_files_fd, reference_profile_files_fd);
         } else {
@@ -1145,13 +1182,16 @@
 
     close(out_fd);
     close(input_fd);
-    if (swap_fd != -1) {
+    if (swap_fd >= 0) {
         close(swap_fd);
     }
     if (use_profiles != 0) {
         close_all_fds(profile_files_fd, "profile_files_fd");
         close_all_fds(reference_profile_files_fd, "reference_profile_files_fd");
     }
+    if (image_fd >= 0) {
+        close(image_fd);
+    }
     return 0;
 
 fail:
@@ -1166,6 +1206,12 @@
         close_all_fds(profile_files_fd, "profile_files_fd");
         close_all_fds(reference_profile_files_fd, "reference_profile_files_fd");
     }
+    if (swap_fd >= 0) {
+        close(swap_fd);
+    }
+    if (image_fd >= 0) {
+        close(image_fd);
+    }
     return -1;
 }
 
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 9472ad6..5b79d3c 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -207,6 +207,11 @@
   int8_t status;
 } AHeartRateEvent;
 
+typedef struct ADynamicSensorEvent {
+    bool  connected;
+    int   handle;
+} ADynamicSensorEvent;
+
 /* NOTE: Must match hardware/sensors.h */
 typedef struct ASensorEvent {
     int32_t version; /* sizeof(struct ASensorEvent) */
@@ -229,6 +234,7 @@
             AUncalibratedEvent uncalibrated_magnetic;
             AMetaDataEvent meta_data;
             AHeartRateEvent heart_rate;
+            ADynamicSensorEvent dynamic_sensor_meta;
         };
         union {
             uint64_t        data[8];
diff --git a/include/gui/ISensorServer.h b/include/gui/ISensorServer.h
index 3dca2a3..571acb5 100644
--- a/include/gui/ISensorServer.h
+++ b/include/gui/ISensorServer.h
@@ -38,6 +38,8 @@
     DECLARE_META_INTERFACE(SensorServer);
 
     virtual Vector<Sensor> getSensorList(const String16& opPackageName) = 0;
+    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName) = 0;
+
     virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
              int mode, const String16& opPackageName) = 0;
     virtual int32_t isDataInjectionEnabled() = 0;
diff --git a/include/gui/Sensor.h b/include/gui/Sensor.h
index 8142be6..3792540 100644
--- a/include/gui/Sensor.h
+++ b/include/gui/Sensor.h
@@ -52,9 +52,13 @@
         TYPE_PROXIMITY      = ASENSOR_TYPE_PROXIMITY
     };
 
-            Sensor();
-            Sensor(struct sensor_t const* hwSensor, int halVersion = 0);
-            ~Sensor();
+    typedef struct {
+        uint8_t b[16];
+    } uuid_t;
+
+    Sensor();
+    Sensor(struct sensor_t const* hwSensor, int halVersion = 0);
+    ~Sensor();
 
     const String8& getName() const;
     const String8& getVendor() const;
@@ -77,6 +81,7 @@
     uint32_t getFlags() const;
     bool isWakeUpSensor() const;
     int32_t getReportingMode() const;
+    const uuid_t& getUuid() const;
 
     // LightFlattenable protocol
     inline bool isFixedSize() const { return false; }
@@ -103,6 +108,7 @@
     int32_t mRequiredAppOp;
     int32_t mMaxDelay;
     uint32_t mFlags;
+    uuid_t  mUuid;
     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/SensorManager.h b/include/gui/SensorManager.h
index 0cff46c..6c6230f 100644
--- a/include/gui/SensorManager.h
+++ b/include/gui/SensorManager.h
@@ -54,7 +54,8 @@
     static SensorManager& getInstanceForPackage(const String16& packageName);
     ~SensorManager();
 
-    ssize_t getSensorList(Sensor const* const** list) const;
+    ssize_t getSensorList(Sensor const* const** list);
+    ssize_t getDynamicSensorList(Vector<Sensor>& list);
     Sensor const* getDefaultSensor(int type);
     sp<SensorEventQueue> createEventQueue(String8 packageName = String8(""), int mode = 0);
     bool isDataInjectionEnabled();
@@ -64,17 +65,17 @@
     void sensorManagerDied();
 
     SensorManager(const String16& opPackageName);
-    status_t assertStateLocked() const;
+    status_t assertStateLocked();
 
 private:
     static Mutex sLock;
     static std::map<String16, SensorManager*> sPackageInstances;
 
-    mutable Mutex mLock;
-    mutable sp<ISensorServer> mSensorServer;
-    mutable Sensor const** mSensorList;
-    mutable Vector<Sensor> mSensors;
-    mutable sp<IBinder::DeathRecipient> mDeathObserver;
+    Mutex mLock;
+    sp<ISensorServer> mSensorServer;
+    Sensor const** mSensorList;
+    Vector<Sensor> mSensors;
+    sp<IBinder::DeathRecipient> mDeathObserver;
     const String16 mOpPackageName;
 };
 
diff --git a/include/media/hardware/HardwareAPI.h b/include/media/hardware/HardwareAPI.h
index 9dd3d96..7a73fbd 100644
--- a/include/media/hardware/HardwareAPI.h
+++ b/include/media/hardware/HardwareAPI.h
@@ -190,6 +190,7 @@
 
 // Structure describing a media image (frame)
 // Currently only supporting YUV
+// @deprecated. Use MediaImage2 instead
 struct MediaImage {
     enum Type {
         MEDIA_IMAGE_TYPE_UNKNOWN = 0,
@@ -219,6 +220,45 @@
     PlaneInfo mPlane[MAX_NUM_PLANES];
 };
 
+struct MediaImage2 {
+    enum Type {
+        MEDIA_IMAGE_TYPE_UNKNOWN = 0,
+        MEDIA_IMAGE_TYPE_YUV,
+        MEDIA_IMAGE_TYPE_YUVA,
+        MEDIA_IMAGE_TYPE_RGB,
+        MEDIA_IMAGE_TYPE_RGBA,
+        MEDIA_IMAGE_TYPE_Y,
+    };
+
+    enum PlaneIndex {
+        Y = 0,
+        U = 1,
+        V = 2,
+        R = 0,
+        G = 1,
+        B = 2,
+        A = 3,
+        MAX_NUM_PLANES = 4,
+    };
+
+    Type mType;
+    uint32_t mNumPlanes;              // number of planes
+    uint32_t mWidth;                  // width of largest plane (unpadded, as in nFrameWidth)
+    uint32_t mHeight;                 // height of largest plane (unpadded, as in nFrameHeight)
+    uint32_t mBitDepth;               // useable bit depth (always MSB)
+    uint32_t mBitDepthAllocated;      // bits per component (must be 8 or 16)
+
+    struct PlaneInfo {
+        uint32_t mOffset;             // offset of first pixel of the plane in bytes
+                                      // from buffer offset
+        int32_t mColInc;              // column increment in bytes
+        int32_t mRowInc;              // row increment in bytes
+        uint32_t mHorizSubsampling;   // subsampling compared to the largest plane
+        uint32_t mVertSubsampling;    // subsampling compared to the largest plane
+    };
+    PlaneInfo mPlane[MAX_NUM_PLANES];
+};
+
 // A pointer to this struct is passed to OMX_GetParameter when the extension
 // index for the 'OMX.google.android.index.describeColorFormat'
 // extension is given.  This method can be called from any component state
@@ -245,6 +285,8 @@
 // For non-YUV packed planar/semiplanar image formats, or if bUsingNativeBuffers
 // is OMX_TRUE and the component does not support this color format with native
 // buffers, the component shall set mNumPlanes to 0, and mType to MEDIA_IMAGE_TYPE_UNKNOWN.
+
+// @deprecated: use DescribeColorFormat2Params
 struct DescribeColorFormatParams {
     OMX_U32 nSize;
     OMX_VERSIONTYPE nVersion;
@@ -260,6 +302,25 @@
     MediaImage sMediaImage;
 };
 
+// A pointer to this struct is passed to OMX_GetParameter when the extension
+// index for the 'OMX.google.android.index.describeColorFormat2'
+// extension is given. This is operationally the same as DescribeColorFormatParams
+// but can be used for HDR and RGBA/YUVA formats.
+struct DescribeColorFormat2Params {
+    OMX_U32 nSize;
+    OMX_VERSIONTYPE nVersion;
+    // input: parameters from OMX_VIDEO_PORTDEFINITIONTYPE
+    OMX_COLOR_FORMATTYPE eColorFormat;
+    OMX_U32 nFrameWidth;
+    OMX_U32 nFrameHeight;
+    OMX_U32 nStride;
+    OMX_U32 nSliceHeight;
+    OMX_BOOL bUsingNativeBuffers;
+
+    // output: fill out the MediaImage2 fields
+    MediaImage2 sMediaImage;
+};
+
 // A pointer to this struct is passed to OMX_SetParameter or OMX_GetParameter
 // when the extension index for the
 // 'OMX.google.android.index.configureVideoTunnelMode' extension is  given.
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
index f581b5c..3a4c7e4 100644
--- a/libs/gui/ISensorServer.cpp
+++ b/libs/gui/ISensorServer.cpp
@@ -35,7 +35,8 @@
 enum {
     GET_SENSOR_LIST = IBinder::FIRST_CALL_TRANSACTION,
     CREATE_SENSOR_EVENT_CONNECTION,
-    ENABLE_DATA_INJECTION
+    ENABLE_DATA_INJECTION,
+    GET_DYNAMIC_SENSOR_LIST,
 };
 
 class BpSensorServer : public BpInterface<ISensorServer>
@@ -65,6 +66,23 @@
         return v;
     }
 
+    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName)
+    {
+        Parcel data, reply;
+        data.writeInterfaceToken(ISensorServer::getInterfaceDescriptor());
+        data.writeString16(opPackageName);
+        remote()->transact(GET_DYNAMIC_SENSOR_LIST, data, &reply);
+        Sensor s;
+        Vector<Sensor> v;
+        uint32_t n = reply.readUint32();
+        v.setCapacity(n);
+        while (n--) {
+            reply.read(s);
+            v.add(s);
+        }
+        return v;
+    }
+
     virtual sp<ISensorEventConnection> createSensorEventConnection(const String8& packageName,
              int mode, const String16& opPackageName)
     {
@@ -124,6 +142,17 @@
             reply->writeInt32(static_cast<int32_t>(ret));
             return NO_ERROR;
         }
+        case GET_DYNAMIC_SENSOR_LIST: {
+            CHECK_INTERFACE(ISensorServer, data, reply);
+            const String16& opPackageName = data.readString16();
+            Vector<Sensor> v(getDynamicSensorList(opPackageName));
+            size_t n = v.size();
+            reply->writeUint32(static_cast<uint32_t>(n));
+            for (size_t i = 0; i < n; i++) {
+                reply->write(v[i]);
+            }
+            return NO_ERROR;
+        }
     }
     return BBinder::onTransact(code, data, reply, flags);
 }
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index 0a0fc4b..0b2b942 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -188,7 +188,7 @@
         if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
             mFlags |= SENSOR_FLAG_WAKE_UP;
         }
-         break;
+        break;
     case SENSOR_TYPE_WAKE_GESTURE:
         mStringType = SENSOR_STRING_TYPE_WAKE_GESTURE;
         mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
@@ -217,6 +217,32 @@
             mFlags |= SENSOR_FLAG_WAKE_UP;
         }
         break;
+    case SENSOR_TYPE_DYNAMIC_SENSOR_META:
+        mStringType = SENSOR_STRING_TYPE_DYNAMIC_SENSOR_META;
+        mFlags = SENSOR_FLAG_SPECIAL_REPORTING_MODE; // special trigger and non-wake up
+        break;
+    case SENSOR_TYPE_POSE_6DOF:
+        mStringType = SENSOR_STRING_TYPE_POSE_6DOF;
+        mFlags |= SENSOR_FLAG_CONTINUOUS_MODE;
+        break;
+    case SENSOR_TYPE_STATIONARY_DETECT:
+        mStringType = SENSOR_STRING_TYPE_STATIONARY_DETECT;
+        mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_MOTION_DETECT:
+        mStringType = SENSOR_STRING_TYPE_MOTION_DETECT;
+        mFlags |= SENSOR_FLAG_ONE_SHOT_MODE;
+        if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+            mFlags |= SENSOR_FLAG_WAKE_UP;
+        }
+        break;
+    case SENSOR_TYPE_HEART_BEAT:
+        mStringType = SENSOR_STRING_TYPE_HEART_BEAT;
+        mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+        break;
     default:
         // Only pipe the stringType, requiredPermission and flags for custom sensors.
         if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->stringType) {
@@ -368,13 +394,18 @@
     return ((mFlags & REPORTING_MODE_MASK) >> REPORTING_MODE_SHIFT);
 }
 
+const Sensor::uuid_t& Sensor::getUuid() const {
+    return mUuid;
+}
+
 size_t Sensor::getFlattenedSize() const
 {
     size_t fixedSize =
-            sizeof(int32_t) * 3 +
-            sizeof(float) * 4 +
-            sizeof(int32_t) * 6 +
-            sizeof(bool);
+            sizeof(mVersion) + sizeof(mHandle) + sizeof(mType) +
+            sizeof(mMinValue) + sizeof(mMaxValue) + sizeof(mResolution) +
+            sizeof(mPower) + sizeof(mMinDelay) + sizeof(mFifoMaxEventCount) +
+            sizeof(mFifoMaxEventCount) + sizeof(mRequiredPermissionRuntime) +
+            sizeof(mRequiredAppOp) + sizeof(mMaxDelay) + sizeof(mFlags) + sizeof(mUuid);
 
     size_t variableSize =
             sizeof(uint32_t) + FlattenableUtils::align<4>(mName.length()) +
@@ -408,6 +439,7 @@
     FlattenableUtils::write(buffer, size, mRequiredAppOp);
     FlattenableUtils::write(buffer, size, mMaxDelay);
     FlattenableUtils::write(buffer, size, mFlags);
+    FlattenableUtils::write(buffer, size, mUuid);
     return NO_ERROR;
 }
 
@@ -419,11 +451,11 @@
         return NO_MEMORY;
     }
 
-    size_t fixedSize =
-            sizeof(int32_t) * 3 +
-            sizeof(float) * 4 +
-            sizeof(int32_t) * 5;
-    if (size < fixedSize) {
+    size_t fixedSize1 =
+            sizeof(mVersion) + sizeof(mHandle) + sizeof(mType) + sizeof(mMinValue) +
+            sizeof(mMaxValue) + sizeof(mResolution) + sizeof(mPower) + sizeof(mMinDelay) +
+            sizeof(mFifoMaxEventCount) + sizeof(mFifoMaxEventCount);
+    if (size < fixedSize1) {
         return NO_MEMORY;
     }
 
@@ -444,10 +476,19 @@
     if (!unflattenString8(buffer, size, mRequiredPermission)) {
         return NO_MEMORY;
     }
+
+    size_t fixedSize2 =
+            sizeof(mRequiredPermissionRuntime) + sizeof(mRequiredAppOp) + sizeof(mMaxDelay) +
+            sizeof(mFlags) + sizeof(mUuid);
+    if (size < fixedSize2) {
+        return NO_MEMORY;
+    }
+
     FlattenableUtils::read(buffer, size, mRequiredPermissionRuntime);
     FlattenableUtils::read(buffer, size, mRequiredAppOp);
     FlattenableUtils::read(buffer, size, mMaxDelay);
     FlattenableUtils::read(buffer, size, mFlags);
+    FlattenableUtils::read(buffer, size, mUuid);
     return NO_ERROR;
 }
 
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index 33608b5..225bfa8 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -89,19 +89,16 @@
 }
 
 SensorManager::SensorManager(const String16& opPackageName)
-    : mSensorList(0), mOpPackageName(opPackageName)
-{
+    : mSensorList(0), mOpPackageName(opPackageName) {
     // okay we're not locked here, but it's not needed during construction
     assertStateLocked();
 }
 
-SensorManager::~SensorManager()
-{
+SensorManager::~SensorManager() {
     free(mSensorList);
 }
 
-void SensorManager::sensorManagerDied()
-{
+void SensorManager::sensorManagerDied() {
     Mutex::Autolock _l(mLock);
     mSensorServer.clear();
     free(mSensorList);
@@ -109,7 +106,7 @@
     mSensors.clear();
 }
 
-status_t SensorManager::assertStateLocked() const {
+status_t SensorManager::assertStateLocked() {
     bool initSensorManager = false;
     if (mSensorServer == NULL) {
         initSensorManager = true;
@@ -136,13 +133,13 @@
         }
 
         class DeathObserver : public IBinder::DeathRecipient {
-            SensorManager& mSensorManger;
+            SensorManager& mSensorManager;
             virtual void binderDied(const wp<IBinder>& who) {
                 ALOGW("sensorservice died [%p]", who.unsafe_get());
-                mSensorManger.sensorManagerDied();
+                mSensorManager.sensorManagerDied();
             }
         public:
-            DeathObserver(SensorManager& mgr) : mSensorManger(mgr) { }
+            DeathObserver(SensorManager& mgr) : mSensorManager(mgr) { }
         };
 
         LOG_ALWAYS_FATAL_IF(mSensorServer.get() == NULL, "getService(SensorService) NULL");
@@ -164,8 +161,7 @@
     return NO_ERROR;
 }
 
-ssize_t SensorManager::getSensorList(Sensor const* const** list) const
-{
+ssize_t SensorManager::getSensorList(Sensor const* const** list) {
     Mutex::Autolock _l(mLock);
     status_t err = assertStateLocked();
     if (err < 0) {
@@ -175,6 +171,19 @@
     return static_cast<ssize_t>(mSensors.size());
 }
 
+ssize_t SensorManager::getDynamicSensorList(Vector<Sensor> & dynamicSensors) {
+    Mutex::Autolock _l(mLock);
+    status_t err = assertStateLocked();
+    if (err < 0) {
+        return static_cast<ssize_t>(err);
+    }
+
+    dynamicSensors = mSensorServer->getDynamicSensorList(mOpPackageName);
+    size_t count = dynamicSensors.size();
+
+    return static_cast<ssize_t>(count);
+}
+
 Sensor const* SensorManager::getDefaultSensor(int type)
 {
     Mutex::Autolock _l(mLock);
diff --git a/services/sensorservice/SensorDevice.cpp b/services/sensorservice/SensorDevice.cpp
index 40d596f..179b1c5 100644
--- a/services/sensorservice/SensorDevice.cpp
+++ b/services/sensorservice/SensorDevice.cpp
@@ -73,6 +73,17 @@
     }
 }
 
+void SensorDevice::handleDynamicSensorConnection(int handle, bool connected) {
+    if (connected) {
+        Info model;
+        mActivationCount.add(handle, model);
+        mSensorDevice->activate(
+                reinterpret_cast<struct sensors_poll_device_t *>(mSensorDevice), handle, 0);
+    } else {
+        mActivationCount.removeItem(handle);
+    }
+}
+
 void SensorDevice::dump(String8& result)
 {
     if (!mSensorModule) return;
diff --git a/services/sensorservice/SensorDevice.h b/services/sensorservice/SensorDevice.h
index c484849..c12630a 100644
--- a/services/sensorservice/SensorDevice.h
+++ b/services/sensorservice/SensorDevice.h
@@ -89,6 +89,7 @@
     bool isClientDisabledLocked(void* ident);
 public:
     ssize_t getSensorList(sensor_t const** list);
+    void handleDynamicSensorConnection(int handle, bool connected);
     status_t initCheck() const;
     int getHalDeviceVersion() const;
     ssize_t poll(sensors_event_t* buffer, size_t count);
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index acad61c..9f8c21b 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -246,9 +246,6 @@
 
 Sensor SensorService::registerSensor(SensorInterface* s)
 {
-    sensors_event_t event;
-    memset(&event, 0, sizeof(event));
-
     const Sensor sensor(s->getSensor());
     // add to the sensor list (returned to clients)
     mSensorList.add(sensor);
@@ -260,6 +257,37 @@
     return sensor;
 }
 
+Sensor SensorService::registerDynamicSensor(SensorInterface* s)
+{
+    Sensor sensor = registerSensor(s);
+    mDynamicSensorList.add(sensor);
+    return sensor;
+}
+
+bool SensorService::unregisterDynamicSensor(int handle) {
+    bool found = false;
+
+    for (size_t i=0 ; i<mSensorList.size() ; i++) {
+        if (mSensorList[i].getHandle() == handle) {
+            mSensorList.removeAt(i);
+            found = true;
+            break;
+        }
+    }
+
+    if (found) {
+        for (size_t i=0 ; i<mDynamicSensorList.size() ; i++) {
+            if (mDynamicSensorList[i].getHandle() == handle) {
+                mDynamicSensorList.removeAt(i);
+            }
+        }
+
+        mSensorMap.removeItem(handle);
+        mLastEventSeen.removeItem(handle);
+    }
+    return found;
+}
+
 Sensor SensorService::registerVirtualSensor(SensorInterface* s)
 {
     Sensor sensor = registerSensor(s);
@@ -593,11 +621,11 @@
             }
         }
 
-        // Map flush_complete_events in the buffer to SensorEventConnections which called flush on
-        // the hardware sensor. mapFlushEventsToConnections[i] will be the SensorEventConnection
-        // mapped to the corresponding flush_complete_event in mSensorEventBuffer[i] if such a
-        // mapping exists (NULL otherwise).
         for (int i = 0; i < count; ++i) {
+            // Map flush_complete_events in the buffer to SensorEventConnections which called flush on
+            // the hardware sensor. mapFlushEventsToConnections[i] will be the SensorEventConnection
+            // mapped to the corresponding flush_complete_event in mSensorEventBuffer[i] if such a
+            // mapping exists (NULL otherwise).
             mMapFlushEventsToConnections[i] = NULL;
             if (mSensorEventBuffer[i].type == SENSOR_TYPE_META_DATA) {
                 const int sensor_handle = mSensorEventBuffer[i].meta_data.sensor;
@@ -607,8 +635,40 @@
                     rec->removeFirstPendingFlushConnection();
                 }
             }
+
+            // handle dynamic sensor meta events, process registration and unregistration of dynamic
+            // sensor based on content of event.
+            if (mSensorEventBuffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META) {
+                if (mSensorEventBuffer[i].dynamic_sensor_meta.connected) {
+                    int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
+                    const sensor_t& dynamicSensor =
+                            *(mSensorEventBuffer[i].dynamic_sensor_meta.sensor);
+                    ALOGI("Dynamic sensor handle 0x%x connected, type %d, name %s",
+                          handle, dynamicSensor.type, dynamicSensor.name);
+
+                    device.handleDynamicSensorConnection(handle, true /*connected*/);
+                    registerDynamicSensor(new HardwareSensor(dynamicSensor));
+
+                } else {
+                    int handle = mSensorEventBuffer[i].dynamic_sensor_meta.handle;
+                    ALOGI("Dynamic sensor handle 0x%x disconnected", handle);
+
+                    device.handleDynamicSensorConnection(handle, false /*connected*/);
+                    if (!unregisterDynamicSensor(handle)) {
+                        ALOGE("Dynamic sensor release error.");
+                    }
+
+                    size_t numConnections = activeConnections.size();
+                    for (size_t i=0 ; i < numConnections; ++i) {
+                        if (activeConnections[i] != NULL) {
+                            activeConnections[i]->removeSensor(handle);
+                        }
+                    }
+                }
+            }
         }
 
+
         // Send our events to clients. Check the state of wake lock for each client and release the
         // lock if none of the clients need it.
         bool needsWakeLock = false;
@@ -693,13 +753,17 @@
 void SensorService::recordLastValueLocked(
         const sensors_event_t* buffer, size_t count) {
     for (size_t i = 0; i < count; i++) {
-        if (buffer[i].type != SENSOR_TYPE_META_DATA) {
-            MostRecentEventLogger* &circular_buf = mLastEventSeen.editValueFor(buffer[i].sensor);
-            if (circular_buf == NULL) {
-                circular_buf = new MostRecentEventLogger(buffer[i].type);
-            }
-            circular_buf->addEvent(buffer[i]);
+        if (buffer[i].type == SENSOR_TYPE_META_DATA ||
+            buffer[i].type == SENSOR_TYPE_DYNAMIC_SENSOR_META ||
+            mLastEventSeen.indexOfKey(buffer[i].sensor) <0 ) {
+            continue;
         }
+
+        MostRecentEventLogger* &circular_buf = mLastEventSeen.editValueFor(buffer[i].sensor);
+        if (circular_buf == NULL) {
+            circular_buf = new MostRecentEventLogger(buffer[i].type);
+        }
+        circular_buf->addEvent(buffer[i]);
     }
 }
 
@@ -729,7 +793,7 @@
 
 bool SensorService::isVirtualSensor(int handle) const {
     SensorInterface* sensor = mSensorMap.valueFor(handle);
-    return sensor->isVirtual();
+    return sensor != NULL && sensor->isVirtual();
 }
 
 bool SensorService::isWakeUpSensorEvent(const sensors_event_t& event) const {
@@ -766,6 +830,23 @@
     return accessibleSensorList;
 }
 
+Vector<Sensor> SensorService::getDynamicSensorList(const String16& opPackageName)
+{
+    Vector<Sensor> accessibleSensorList;
+    for (size_t i = 0; i < mDynamicSensorList.size(); i++) {
+        Sensor sensor = mDynamicSensorList[i];
+        if (canAccessSensor(sensor, "getDynamicSensorList", opPackageName)) {
+            accessibleSensorList.add(sensor);
+        } else {
+            ALOGI("Skipped sensor %s because it requires permission %s and app op %d",
+                  sensor.getName().string(),
+                  sensor.getRequiredPermission().string(),
+                  sensor.getRequiredAppOp());
+        }
+    }
+    return accessibleSensorList;
+}
+
 sp<ISensorEventConnection> SensorService::createSensorEventConnection(const String8& packageName,
         int requestedMode, const String16& opPackageName) {
     // Only 2 modes supported for a SensorEventConnection ... NORMAL and DATA_INJECTION.
@@ -950,8 +1031,7 @@
     // one should be trigger by a change in value). Also if this sensor isn't
     // already active, don't call flush().
     if (err == NO_ERROR &&
-            sensor->getSensor().getReportingMode() != AREPORTING_MODE_ONE_SHOT &&
-            sensor->getSensor().getReportingMode() != AREPORTING_MODE_ON_CHANGE &&
+            sensor->getSensor().getReportingMode() == AREPORTING_MODE_CONTINUOUS &&
             rec->getNumConnections() > 1) {
         connection->setFirstFlushPending(handle, true);
         status_t err_flush = sensor->flush(connection.get(), handle);
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 080a550..ef4516b 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -149,6 +149,7 @@
 
     // ISensorServer interface
     virtual Vector<Sensor> getSensorList(const String16& opPackageName);
+    virtual Vector<Sensor> getDynamicSensorList(const String16& opPackageName);
     virtual sp<ISensorEventConnection> createSensorEventConnection(
             const String8& packageName,
             int requestedMode, const String16& opPackageName);
@@ -165,6 +166,8 @@
     static void sortEventBuffer(sensors_event_t* buffer, size_t count);
     Sensor registerSensor(SensorInterface* sensor);
     Sensor registerVirtualSensor(SensorInterface* sensor);
+    Sensor registerDynamicSensor(SensorInterface* sensor);
+    bool unregisterDynamicSensor(int handle);
     status_t cleanupWithoutDisable(const sp<SensorEventConnection>& connection, int handle);
     status_t cleanupWithoutDisableLocked(const sp<SensorEventConnection>& connection, int handle);
     void cleanupAutoDisabledSensorLocked(const sp<SensorEventConnection>& connection,
@@ -212,6 +215,7 @@
     Vector<Sensor> mSensorList;
     Vector<Sensor> mUserSensorListDebug;
     Vector<Sensor> mUserSensorList;
+    Vector<Sensor> mDynamicSensorList;
     DefaultKeyedVector<int, SensorInterface*> mSensorMap;
     Vector<SensorInterface *> mVirtualSensorList;
     status_t mInitCheck;