Merge "[LSC] Add LOCAL_LICENSE_KINDS to frameworks/av"
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index e1fe257..a70cc4b 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -1090,6 +1090,15 @@
      * (ACAMERA_LENS_OPTICAL_STABILIZATION_MODE), turning both modes on may
      * produce undesirable interaction, so it is recommended not to enable
      * both at the same time.</p>
+     * <p>If video stabilization is set to "PREVIEW_STABILIZATION",
+     * ACAMERA_LENS_OPTICAL_STABILIZATION_MODE is overridden. The camera sub-system may choose
+     * to turn on hardware based image stabilization in addition to software based stabilization
+     * if it deems that appropriate.
+     * This key may be a part of the available session keys, which camera clients may
+     * query via
+     * {@link ACameraManager_getCameraCharacteristics }.
+     * If this is the case, changing this key over the life-time of a capture session may
+     * cause delays / glitches.</p>
      *
      * @see ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE
      * @see ACAMERA_LENS_OPTICAL_STABILIZATION_MODE
@@ -2571,12 +2580,18 @@
      * <p>If a camera device supports both OIS and digital image stabilization
      * (ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE), turning both modes on may produce undesirable
      * interaction, so it is recommended not to enable both at the same time.</p>
+     * <p>If ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE is set to "PREVIEW_STABILIZATION",
+     * ACAMERA_LENS_OPTICAL_STABILIZATION_MODE is overridden. The camera sub-system may choose
+     * to turn on hardware based image stabilization in addition to software based stabilization
+     * if it deems that appropriate. This key's value in the capture result will reflect which
+     * OIS mode was chosen.</p>
      * <p>Not all devices will support OIS; see
      * ACAMERA_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION for
      * available controls.</p>
      *
      * @see ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE
      * @see ACAMERA_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION
+     * @see ACAMERA_LENS_OPTICAL_STABILIZATION_MODE
      */
     ACAMERA_LENS_OPTICAL_STABILIZATION_MODE =                   // byte (acamera_metadata_enum_android_lens_optical_stabilization_mode_t)
             ACAMERA_LENS_START + 4,
@@ -8014,6 +8029,17 @@
      */
     ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE_ON                      = 1,
 
+    /**
+     * <p>Preview stabilization, where the preview in addition to all other non-RAW streams are
+     * stabilized with the same quality of stabilization, is enabled. This mode aims to give
+     * clients a 'what you see is what you get' effect. In this mode, the FoV reduction will
+     * be a maximum of 20 % both horizontally and vertically
+     * (10% from left, right, top, bottom) for the given zoom ratio / crop region.
+     * The resultant FoV will also be the same across all processed streams
+     * (that have the same aspect ratio).</p>
+     */
+    ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION   = 2,
+
 } acamera_metadata_enum_android_control_video_stabilization_mode_t;
 
 // ACAMERA_CONTROL_AE_STATE
diff --git a/drm/drmserver/drmserver.rc b/drm/drmserver/drmserver.rc
index eb176c1..0319ff9 100644
--- a/drm/drmserver/drmserver.rc
+++ b/drm/drmserver/drmserver.rc
@@ -3,7 +3,7 @@
     class main
     user drm
     group drm system inet drmrpc readproc
-    writepid /dev/cpuset/foreground/tasks
+    task_profiles ProcessCapacityHigh
 
 on property:drm.service.enabled=true
     start drm
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
index 9afd3d7..ec4517d 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service-lazy.clearkey.rc
@@ -11,4 +11,4 @@
     user media
     group media mediadrm
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
+    task_profiles ProcessCapacityHigh
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
index c1abe7f..3b48cf2 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.2-service.clearkey.rc
@@ -10,4 +10,4 @@
     user media
     group media mediadrm
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
+    task_profiles ProcessCapacityHigh
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service-lazy.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service-lazy.clearkey.rc
index 1e0d431..6e64978 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service-lazy.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service-lazy.clearkey.rc
@@ -13,4 +13,4 @@
     user media
     group media mediadrm
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
+    task_profiles ProcessCapacityHigh
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service.clearkey.rc
index 8130511..e302e1b 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.3-service.clearkey.rc
@@ -11,4 +11,4 @@
     user media
     group media mediadrm
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
+    task_profiles ProcessCapacityHigh
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service-lazy.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service-lazy.clearkey.rc
index 46aba88..84a63a1 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service-lazy.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service-lazy.clearkey.rc
@@ -15,4 +15,4 @@
     user media
     group media mediadrm
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
+    task_profiles ProcessCapacityHigh
diff --git a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service.clearkey.rc b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service.clearkey.rc
index 8186933..649599e 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service.clearkey.rc
+++ b/drm/mediadrm/plugins/clearkey/hidl/android.hardware.drm@1.4-service.clearkey.rc
@@ -13,4 +13,4 @@
     user media
     group media mediadrm
     ioprio rt 4
-    writepid /dev/cpuset/foreground/tasks
+    task_profiles ProcessCapacityHigh
diff --git a/media/libheadtracking/SensorPoseProvider-example.cpp b/media/libheadtracking/SensorPoseProvider-example.cpp
index a246e8b..88e222e 100644
--- a/media/libheadtracking/SensorPoseProvider-example.cpp
+++ b/media/libheadtracking/SensorPoseProvider-example.cpp
@@ -40,7 +40,7 @@
 class Listener : public SensorPoseProvider::Listener {
   public:
     void onPose(int64_t timestamp, int32_t handle, const Pose3f& pose,
-                const std::optional<Twist3f>& twist) override {
+                const std::optional<Twist3f>& twist, bool isNewReference) override {
         int64_t now = elapsedRealtimeNano();
 
         std::cout << "onPose t=" << timestamp
@@ -53,7 +53,7 @@
         } else {
             std::cout << "<none>";
         }
-        std::cout << std::endl;
+        std::cout << " isNewReference=" << isNewReference << std::endl;
     }
 };
 
@@ -67,11 +67,15 @@
 
     std::unique_ptr<SensorPoseProvider> provider =
             SensorPoseProvider::create(kPackageName, &listener);
-    int32_t headHandle = provider->startSensor(headSensor->getHandle(), 500ms);
+    if (!provider->startSensor(headSensor->getHandle(), 500ms)) {
+        std::cout << "Failed to start head sensor" << std::endl;
+    }
     sleep(2);
-    provider->startSensor(screenSensor->getHandle(), 500ms);
+    if (!provider->startSensor(screenSensor->getHandle(), 500ms)) {
+        std::cout << "Failed to start screenSensor sensor" << std::endl;
+    }
     sleep(2);
-    provider->stopSensor(headHandle);
+    provider->stopSensor(headSensor->getHandle());
     sleep(2);
     return 0;
 }
diff --git a/media/libheadtracking/SensorPoseProvider.cpp b/media/libheadtracking/SensorPoseProvider.cpp
index c4c031d..ec5e1ec 100644
--- a/media/libheadtracking/SensorPoseProvider.cpp
+++ b/media/libheadtracking/SensorPoseProvider.cpp
@@ -24,6 +24,7 @@
 #include <map>
 #include <thread>
 
+#include <android-base/thread_annotations.h>
 #include <log/log_main.h>
 #include <sensor/Sensor.h>
 #include <sensor/SensorEventQueue.h>
@@ -86,7 +87,7 @@
         if (mSensor != SensorPoseProvider::INVALID_HANDLE) {
             int ret = mQueue->disableSensor(mSensor);
             if (ret) {
-                ALOGE("Failed to disable sensor: %s\n", strerror(ret));
+                ALOGE("Failed to disable sensor: %s", strerror(ret));
             }
         }
     }
@@ -123,9 +124,23 @@
     }
 
     bool startSensor(int32_t sensor, std::chrono::microseconds samplingPeriod) override {
+        // Figure out the sensor's data format.
+        DataFormat format = getSensorFormat(sensor);
+        if (format == DataFormat::kUnknown) {
+            ALOGE("Unknown format for sensor %" PRId32, sensor);
+            return false;
+        }
+
+        {
+            std::lock_guard lock(mMutex);
+            mEnabledSensorFormats.emplace(sensor, format);
+        }
+
         // Enable the sensor.
         if (mQueue->enableSensor(sensor, samplingPeriod.count(), 0, 0)) {
             ALOGE("Failed to enable sensor");
+            std::lock_guard lock(mMutex);
+            mEnabledSensorFormats.erase(sensor);
             return false;
         }
 
@@ -133,14 +148,32 @@
         return true;
     }
 
-    void stopSensor(int handle) override { mEnabledSensors.erase(handle); }
+    void stopSensor(int handle) override {
+        mEnabledSensors.erase(handle);
+        std::lock_guard lock(mMutex);
+        mEnabledSensorFormats.erase(handle);
+    }
 
   private:
+    enum DataFormat {
+        kUnknown,
+        kQuaternion,
+        kRotationVectorsAndFlags,
+    };
+
+    struct PoseEvent {
+        Pose3f pose;
+        std::optional<Twist3f> twist;
+        bool isNewReference;
+    };
+
     sp<Looper> mLooper;
     Listener* const mListener;
-
+    SensorManager* const mSensorManager;
     std::thread mThread;
+    std::mutex mMutex;
     std::map<int32_t, SensorEnableGuard> mEnabledSensors;
+    std::map<int32_t, DataFormat> mEnabledSensorFormats GUARDED_BY(mMutex);
     sp<SensorEventQueue> mQueue;
 
     // We must do some of the initialization operations on the worker thread, because the API relies
@@ -153,21 +186,19 @@
 
     SensorPoseProviderImpl(const char* packageName, Listener* listener)
         : mListener(listener),
-          mThread([this, p = std::string(packageName)] { threadFunc(p.c_str()); }) {}
+          mSensorManager(&SensorManager::getInstanceForPackage(String16(packageName))),
+          mThread([this] { threadFunc(); }) {}
 
     void initFinished(bool success) { mInitPromise.set_value(success); }
 
     bool waitInitFinished() { return mInitPromise.get_future().get(); }
 
-    void threadFunc(const char* packageName) {
+    void threadFunc() {
         // Obtain looper.
         mLooper = Looper::prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
 
-        // Obtain sensor manager.
-        SensorManager& sensorManager = SensorManager::getInstanceForPackage(String16(packageName));
-
         // Create event queue.
-        mQueue = sensorManager.createEventQueue();
+        mQueue = mSensorManager->createEventQueue();
 
         if (mQueue == nullptr) {
             ALOGE("Failed to create a sensor event queue");
@@ -217,24 +248,98 @@
     }
 
     void handleEvent(const ASensorEvent& event) {
-        auto value = parseEvent(event);
-        mListener->onPose(event.timestamp, event.sensor, std::get<0>(value), std::get<1>(value));
+        DataFormat format;
+        {
+            std::lock_guard lock(mMutex);
+            auto iter = mEnabledSensorFormats.find(event.sensor);
+            if (iter == mEnabledSensorFormats.end()) {
+                // This can happen if we have any pending events shortly after stopping.
+                return;
+            }
+            format = iter->second;
+        }
+        auto value = parseEvent(event, format);
+        mListener->onPose(event.timestamp, event.sensor, value.pose, value.twist,
+                          value.isNewReference);
     }
 
-    static std::tuple<Pose3f, std::optional<Twist3f>> parseEvent(const ASensorEvent& event) {
+    DataFormat getSensorFormat(int32_t handle) {
+        std::optional<const Sensor> sensor = getSensorByHandle(handle);
+        if (!sensor) {
+            ALOGE("Sensor not found: %d", handle);
+            return DataFormat::kUnknown;
+        }
+        if (sensor->getType() == ASENSOR_TYPE_ROTATION_VECTOR ||
+            sensor->getType() == ASENSOR_TYPE_GAME_ROTATION_VECTOR) {
+            return DataFormat::kQuaternion;
+        }
+
+        if (sensor->getStringType() == "com.google.hardware.sensor.hid_dynamic.headtracker") {
+            return DataFormat::kRotationVectorsAndFlags;
+        }
+
+        return DataFormat::kUnknown;
+    }
+
+    std::optional<const Sensor> getSensorByHandle(int32_t handle) {
+        const Sensor* const* list;
+        ssize_t size;
+
+        // Search static sensor list.
+        size = mSensorManager->getSensorList(&list);
+        if (size < 0) {
+            ALOGE("getSensorList failed with error code %zd", size);
+            return std::nullopt;
+        }
+        for (size_t i = 0; i < size; ++i) {
+            if (list[i]->getHandle() == handle) {
+                return *list[i];
+            }
+        }
+
+        // Search dynamic sensor list.
+        Vector<Sensor> dynList;
+        size = mSensorManager->getDynamicSensorList(dynList);
+        if (size < 0) {
+            ALOGE("getDynamicSensorList failed with error code %zd", size);
+            return std::nullopt;
+        }
+        for (size_t i = 0; i < size; ++i) {
+            if (dynList[i].getHandle() == handle) {
+                return dynList[i];
+            }
+        }
+
+        return std::nullopt;
+    }
+
+    static PoseEvent parseEvent(const ASensorEvent& event, DataFormat format) {
         // TODO(ytai): Add more types.
-        switch (event.type) {
-            case ASENSOR_TYPE_ROTATION_VECTOR:
-            case ASENSOR_TYPE_GAME_ROTATION_VECTOR: {
+        switch (format) {
+            case DataFormat::kQuaternion: {
                 Eigen::Quaternionf quat(event.data[3], event.data[0], event.data[1], event.data[2]);
                 // Adapt to different frame convention.
                 quat *= rotateX(-M_PI_2);
-                return std::make_tuple(Pose3f(quat), std::optional<Twist3f>());
+                return PoseEvent{Pose3f(quat), std::optional<Twist3f>(), false};
+            }
+
+            case DataFormat::kRotationVectorsAndFlags: {
+                // Custom sensor, assumed to contain:
+                // 3 floats representing orientation as a rotation vector (in rad).
+                // 3 floats representing angular velocity as a rotation vector (in rad/s).
+                // 1 uint32_t of flags, where:
+                // - LSb is '1' iff the given sample is the first one in a new frame of reference.
+                // - The rest of the bits are reserved for future use.
+                Eigen::Vector3f rotation = {event.data[0], event.data[1], event.data[2]};
+                Eigen::Vector3f twist = {event.data[3], event.data[4], event.data[5]};
+                Eigen::Quaternionf quat = rotationVectorToQuaternion(rotation);
+                uint32_t flags = *reinterpret_cast<const uint32_t*>(&event.data[6]);
+                return PoseEvent{Pose3f(quat), Twist3f(Eigen::Vector3f::Zero(), twist),
+                                 (flags & (1 << 0)) != 0};
             }
 
             default:
-                ALOGE("Unsupported sensor type: %" PRId32, event.type);
-                return std::make_tuple(Pose3f(), std::optional<Twist3f>());
+                LOG_ALWAYS_FATAL("Unexpected sensor type: %d", static_cast<int>(format));
         }
     }
 };
diff --git a/media/libheadtracking/include/media/SensorPoseProvider.h b/media/libheadtracking/include/media/SensorPoseProvider.h
index 1a5deb0..d2a6b77 100644
--- a/media/libheadtracking/include/media/SensorPoseProvider.h
+++ b/media/libheadtracking/include/media/SensorPoseProvider.h
@@ -61,7 +61,7 @@
         virtual ~Listener() = default;
 
         virtual void onPose(int64_t timestamp, int32_t handle, const Pose3f& pose,
-                            const std::optional<Twist3f>& twist) = 0;
+                            const std::optional<Twist3f>& twist, bool isNewReference) = 0;
     };
 
     /**
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 1c9b9e4..5215c1b 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -949,6 +949,9 @@
         mVideoWidth = ext1;
         mVideoHeight = ext2;
         break;
+    case MEDIA_STARTED:
+        ALOGV("Received media started message");
+        break;
     case MEDIA_NOTIFY_TIME:
         ALOGV("Received notify time message");
         break;
diff --git a/media/libmediametrics/include/media/MediaMetricsItem.h b/media/libmediametrics/include/media/MediaMetricsItem.h
index 428992c..347fe28 100644
--- a/media/libmediametrics/include/media/MediaMetricsItem.h
+++ b/media/libmediametrics/include/media/MediaMetricsItem.h
@@ -470,11 +470,10 @@
     status_t extract(std::string *val, const char **bufferpptr, const char *bufferptrmax) {
         const char *ptr = *bufferpptr;
         while (*ptr != 0) {
-            if (ptr >= bufferptrmax) {
+            if (++ptr >= bufferptrmax) {
                 ALOGE("%s: buffer exceeded", __func__);
                 return BAD_VALUE;
             }
-            ++ptr;
         }
         const size_t size = (ptr - *bufferpptr) + 1;
         *val = *bufferpptr;
diff --git a/media/utils/ServiceUtilities.cpp b/media/utils/ServiceUtilities.cpp
index 9620d24..4f0909b 100644
--- a/media/utils/ServiceUtilities.cpp
+++ b/media/utils/ServiceUtilities.cpp
@@ -102,7 +102,11 @@
     AttributionSourceState myAttributionSource;
     myAttributionSource.uid = VALUE_OR_FATAL(android::legacy2aidl_uid_t_int32_t(getuid()));
     myAttributionSource.pid = VALUE_OR_FATAL(android::legacy2aidl_pid_t_int32_t(getpid()));
-    myAttributionSource.token = sp<BBinder>::make();
+    if (callerAttributionSource.token != nullptr) {
+        myAttributionSource.token = callerAttributionSource.token;
+    } else {
+        myAttributionSource.token = sp<BBinder>::make();
+    }
     myAttributionSource.next.push_back(nextAttributionSource);
 
     return std::optional<AttributionSourceState>{myAttributionSource};
diff --git a/services/audiopolicy/service/SpatializerPoseController.cpp b/services/audiopolicy/service/SpatializerPoseController.cpp
index eb23298..ffedf63 100644
--- a/services/audiopolicy/service/SpatializerPoseController.cpp
+++ b/services/audiopolicy/service/SpatializerPoseController.cpp
@@ -224,13 +224,19 @@
 }
 
 void SpatializerPoseController::onPose(int64_t timestamp, int32_t sensor, const Pose3f& pose,
-                                       const std::optional<Twist3f>& twist) {
+                                       const std::optional<Twist3f>& twist, bool isNewReference) {
     std::lock_guard lock(mMutex);
     if (sensor == mHeadSensor) {
         mProcessor->setWorldToHeadPose(timestamp, pose, twist.value_or(Twist3f()));
+        if (isNewReference) {
+            mProcessor->recenter(true, false);
+        }
     }
     if (sensor == mScreenSensor) {
         mProcessor->setWorldToScreenPose(timestamp, pose);
+        if (isNewReference) {
+            mProcessor->recenter(false, true);
+        }
     }
 }
 
diff --git a/services/audiopolicy/service/SpatializerPoseController.h b/services/audiopolicy/service/SpatializerPoseController.h
index c579622..2b5c189 100644
--- a/services/audiopolicy/service/SpatializerPoseController.h
+++ b/services/audiopolicy/service/SpatializerPoseController.h
@@ -130,7 +130,7 @@
     bool mCalculated = false;
 
     void onPose(int64_t timestamp, int32_t sensor, const media::Pose3f& pose,
-                const std::optional<media::Twist3f>& twist) override;
+                const std::optional<media::Twist3f>& twist, bool isNewReference) override;
 
     /**
      * Calculates the new outputs and updates internal state. Must be called with the lock held.