Merge "Multi-layer blur support"
diff --git a/cmds/installd/dexopt.cpp b/cmds/installd/dexopt.cpp
index f95e445..70bbc33 100644
--- a/cmds/installd/dexopt.cpp
+++ b/cmds/installd/dexopt.cpp
@@ -299,9 +299,10 @@
 // Namespace for Android Runtime flags applied during boot time.
 static const char* RUNTIME_NATIVE_BOOT_NAMESPACE = "runtime_native_boot";
 // Feature flag name for running the JIT in Zygote experiment, b/119800099.
-static const char* ENABLE_APEX_IMAGE = "enable_apex_image";
-// Location of the apex image.
-static const char* kApexImage = "/system/framework/apex.art";
+static const char* ENABLE_JITZYGOTE_IMAGE = "enable_apex_image";
+// Location of the JIT Zygote image.
+static const char* kJitZygoteImage =
+    "boot.art:/nonx/boot-framework.art!/system/etc/boot-image.prof";
 
 // Phenotype property name for enabling profiling the boot class path.
 static const char* PROFILE_BOOT_CLASS_PATH = "profilebootclasspath";
@@ -405,9 +406,9 @@
                 GetBoolProperty(kMinidebugInfoSystemProperty, kMinidebugInfoSystemPropertyDefault);
 
         std::string boot_image;
-        std::string use_apex_image =
+        std::string use_jitzygote_image =
             server_configurable_flags::GetServerConfigurableFlag(RUNTIME_NATIVE_BOOT_NAMESPACE,
-                                                                 ENABLE_APEX_IMAGE,
+                                                                 ENABLE_JITZYGOTE_IMAGE,
                                                                  /*default_value=*/ "");
 
         std::string profile_boot_class_path = GetProperty("dalvik.vm.profilebootclasspath", "");
@@ -417,10 +418,10 @@
                 PROFILE_BOOT_CLASS_PATH,
                 /*default_value=*/ profile_boot_class_path);
 
-        if (use_apex_image == "true" || profile_boot_class_path == "true") {
-          boot_image = StringPrintf("-Ximage:%s", kApexImage);
+        if (use_jitzygote_image == "true" || profile_boot_class_path == "true") {
+          boot_image = StringPrintf("--boot-image=%s", kJitZygoteImage);
         } else {
-          boot_image = MapPropertyToArg("dalvik.vm.boot-image", "-Ximage:%s");
+          boot_image = MapPropertyToArg("dalvik.vm.boot-image", "--boot-image=%s");
         }
 
         // clang FORTIFY doesn't let us use strlen in constant array bounds, so we
@@ -513,7 +514,8 @@
         AddArg(instruction_set_variant_arg);
         AddArg(instruction_set_features_arg);
 
-        AddRuntimeArg(boot_image);
+        AddArg(boot_image);
+
         AddRuntimeArg(bootclasspath);
         AddRuntimeArg(dex2oat_Xms_arg);
         AddRuntimeArg(dex2oat_Xmx_arg);
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index 3ff9d11..7c989f6 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -73,7 +73,7 @@
     for (const apex::ApexFile& apex_file : active_packages) {
         const std::string& package_path = apex_file.GetPath();
         base::Result<void> status = apex::deactivatePackage(package_path);
-        if (!status) {
+        if (!status.ok()) {
             LOG(ERROR) << "Failed to deactivate " << package_path << ": "
                        << status.error();
         }
diff --git a/include/android/bitmap.h b/include/android/bitmap.h
index 412fc6b..727a4af 100644
--- a/include/android/bitmap.h
+++ b/include/android/bitmap.h
@@ -81,8 +81,8 @@
 
 enum {
     /** If this bit is set in AndroidBitmapInfo.flags, the Bitmap uses the
-      * HARDWARE Config, and its AHardwareBuffer can be retrieved via
-      * AndroidBitmap_getHardwareBuffer.
+      * HARDWARE Config, and its {@link AHardwareBuffer} can be retrieved via
+      * {@link AndroidBitmap_getHardwareBuffer}.
       */
     ANDROID_BITMAP_FLAGS_IS_HARDWARE = 1 << 31,
 };
@@ -120,10 +120,10 @@
 #if __ANDROID_API__ >= 30
 
 /**
- * Given a java bitmap object, return its ADataSpace.
+ * Given a java bitmap object, return its {@link ADataSpace}.
  *
- * Note that ADataSpace only exposes a few values. This may return
- * ADATASPACE_UNKNOWN, even for Named ColorSpaces, if they have no
+ * Note that {@link ADataSpace} only exposes a few values. This may return
+ * {@link ADATASPACE_UNKNOWN}, even for Named ColorSpaces, if they have no
  * corresponding ADataSpace.
  */
 int32_t AndroidBitmap_getDataSpace(JNIEnv* env, jobject jbitmap)  __INTRODUCED_IN(30);
@@ -206,17 +206,17 @@
  *  @param dataspace {@link ADataSpace} describing the color space of the
  *                   pixels.
  *  @param pixels Pointer to pixels to compress.
- *  @param format (@link AndroidBitmapCompressFormat} to compress to.
+ *  @param format {@link AndroidBitmapCompressFormat} to compress to.
  *  @param quality Hint to the compressor, 0-100. The value is interpreted
  *                 differently depending on the
  *                 {@link AndroidBitmapCompressFormat}.
  *  @param userContext User-defined data which will be passed to the supplied
  *                     {@link AndroidBitmap_CompressWriteFunc} each time it is
  *                     called. May be null.
- *  @parm fn Function that writes the compressed data. Will be called each time
- *           the compressor has compressed more data that is ready to be
- *           written. May be called more than once for each call to this method.
- *           May not be null.
+ *  @param fn Function that writes the compressed data. Will be called each time
+ *            the compressor has compressed more data that is ready to be
+ *            written. May be called more than once for each call to this method.
+ *            May not be null.
  *  @return AndroidBitmap functions result code.
  */
 int AndroidBitmap_compress(const AndroidBitmapInfo* info,
@@ -235,11 +235,11 @@
  *
  *  @param bitmap Handle to an android.graphics.Bitmap.
  *  @param outBuffer On success, is set to a pointer to the
- *         AHardwareBuffer associated with bitmap. This acquires
+ *         {@link AHardwareBuffer} associated with bitmap. This acquires
  *         a reference on the buffer, and the client must call
- *         AHardwareBuffer_release when finished with it.
+ *         {@link AHardwareBuffer_release} when finished with it.
  *  @return AndroidBitmap functions result code.
- *          ANDROID_BITMAP_RESULT_BAD_PARAMETER if bitmap is not a
+ *          {@link ANDROID_BITMAP_RESULT_BAD_PARAMETER} if bitmap is not a
  *          HARDWARE Bitmap.
  */
 int AndroidBitmap_getHardwareBuffer(JNIEnv* env, jobject bitmap,
diff --git a/include/android/imagedecoder.h b/include/android/imagedecoder.h
index 6e5da52..3a87da0 100644
--- a/include/android/imagedecoder.h
+++ b/include/android/imagedecoder.h
@@ -20,9 +20,18 @@
  * Functions for converting encoded images into RGBA pixels.
  *
  * Similar to the Java counterpart android.graphics.ImageDecoder, it can be used
- * to decode images like PNG, JPEG, GIF, WEBP and HEIF. It has similar options
- * for scaling, cropping, and choosing the output format. Unlike the Java API,
- * which can create an android.graphics.Bitmap or
+ * to decode images in the following formats:
+ * - JPEG
+ * - PNG
+ * - GIF
+ * - WebP
+ * - BMP
+ * - ICO
+ * - WBMP
+ * - HEIF
+ * - Digital negatives (via the DNG SDK)
+ * <p>It has similar options for scaling, cropping, and choosing the output format.
+ * Unlike the Java API, which can create an android.graphics.Bitmap or
  * android.graphics.drawable.Drawable object, AImageDecoder decodes directly
  * into memory provided by the client. For more information, see the
  * <a href="https://developer.android.com/ndk/guides/image-decoder">Image decoder</a>
@@ -62,7 +71,7 @@
      */
     ANDROID_IMAGE_DECODER_SUCCESS = 0,
     /**
-     * The input was incomplete.
+     * The input is incomplete.
      */
     ANDROID_IMAGE_DECODER_INCOMPLETE = -1,
     /**
@@ -80,7 +89,7 @@
      */
     ANDROID_IMAGE_DECODER_INVALID_SCALE = -4,
     /**
-     * Some other parameter was bad.
+     * Some other parameter is invalid.
      */
     ANDROID_IMAGE_DECODER_BAD_PARAMETER = -5,
     /**
@@ -133,6 +142,19 @@
  *                   responsible for calling {@link AImageDecoder_delete} on it.
  * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
  *         indicating the reason for the failure.
+ *
+ * Errors:
+ * - {@link ANDROID_IMAGE_DECODER_INCOMPLETE}: The asset was truncated before
+ *   reading the image header.
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: One of the parameters is
+ *   null.
+ * - {@link ANDROID_IMAGE_DECODER_INVALID_INPUT}: There is an error in the
+ *   header.
+ * - {@link ANDROID_IMAGE_DECODER_SEEK_ERROR}: The asset failed to seek.
+ * - {@link ANDROID_IMAGE_DECODER_INTERNAL_ERROR}: Some other error, like a
+ *   failure to allocate memory.
+ * - {@link ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT}: The format is not
+ *   supported.
  */
 int AImageDecoder_createFromAAsset(struct AAsset* asset, AImageDecoder** outDecoder)
         __INTRODUCED_IN(30);
@@ -149,6 +171,19 @@
  *                   responsible for calling {@link AImageDecoder_delete} on it.
  * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
  *         indicating the reason for the failure.
+ *
+ * Errors:
+ * - {@link ANDROID_IMAGE_DECODER_INCOMPLETE}: The file was truncated before
+ *   reading the image header.
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The {@link AImageDecoder} is
+ *   null, or |fd| does not represent a valid, seekable file descriptor.
+ * - {@link ANDROID_IMAGE_DECODER_INVALID_INPUT}: There is an error in the
+ *   header.
+ * - {@link ANDROID_IMAGE_DECODER_SEEK_ERROR}: The descriptor failed to seek.
+ * - {@link ANDROID_IMAGE_DECODER_INTERNAL_ERROR}: Some other error, like a
+ *   failure to allocate memory.
+ * - {@link ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT}: The format is not
+ *   supported.
  */
 int AImageDecoder_createFromFd(int fd, AImageDecoder** outDecoder) __INTRODUCED_IN(30);
 
@@ -163,7 +198,19 @@
  *                   a newly created {@link AImageDecoder}. Caller is
  *                   responsible for calling {@link AImageDecoder_delete} on it.
  * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
- *         indicating reason for the failure.
+ *         indicating the reason for the failure.
+ *
+ * Errors:
+ * - {@link ANDROID_IMAGE_DECODER_INCOMPLETE}: The encoded image was truncated before
+ *   reading the image header.
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: One of the parameters is
+ *   invalid.
+ * - {@link ANDROID_IMAGE_DECODER_INVALID_INPUT}: There is an error in the
+ *   header.
+ * - {@link ANDROID_IMAGE_DECODER_INTERNAL_ERROR}: Some other error, like a
+ *   failure to allocate memory.
+ * - {@link ANDROID_IMAGE_DECODER_UNSUPPORTED_FORMAT}: The format is not
+ *   supported.
  */
 int AImageDecoder_createFromBuffer(const void* buffer, size_t length,
                                    AImageDecoder** outDecoder) __INTRODUCED_IN(30);
@@ -177,11 +224,18 @@
  * Choose the desired output format.
  *
  * @param format {@link AndroidBitmapFormat} to use for the output.
- * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} if the format is compatible
- *         with the image and {@link ANDROID_IMAGE_DECODER_INVALID_CONVERSION}
- *         otherwise. In the latter case, the {@link AImageDecoder} uses the
- *         format it was already planning to use (either its default
- *         or a previously successful setting from this function).
+ * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
+ *         indicating the reason for the failure. On failure, the
+ *         {@link AImageDecoder} uses the format it was already planning
+ *         to use (either its default or a previously successful setting
+ *         from this function).
+ *
+ * Errors:
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
+ *   {@link AImageDecoder} is null or |format| does not correspond to an
+ *   {@link AndroidBitmapFormat}.
+ * - {@link ANDROID_IMAGE_DECODER_INVALID_CONVERSION}: The
+ *   {@link AndroidBitmapFormat} is incompatible with the image.
  */
 int AImageDecoder_setAndroidBitmapFormat(AImageDecoder*,
         int32_t format) __INTRODUCED_IN(30);
@@ -194,11 +248,15 @@
  * opaque image.
  *
  * @param unpremultipliedRequired Pass true to leave the pixels unpremultiplied.
- * @return an enum describing whether the call succeeded.
- *         - {@link ANDROID_IMAGE_DECODER_SUCCESS} on success
- *         - {@link ANDROID_IMAGE_DECODER_INVALID_CONVERSION} if the conversion
- *           is not possible
- *         - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} for bad parameters
+ * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
+ *         indicating the reason for the failure.
+ *
+ * Errors:
+ * - {@link ANDROID_IMAGE_DECODER_INVALID_CONVERSION}: Unpremultiplied is not
+ *   possible due to an existing scale set by
+ *   {@link AImageDecoder_setTargetSize}.
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
+ *   {@link AImageDecoder} is null.
  */
 int AImageDecoder_setUnpremultipliedRequired(AImageDecoder*,
                                              bool unpremultipliedRequired) __INTRODUCED_IN(30);
@@ -215,10 +273,13 @@
  *                  {@link AImageDecoderHeaderInfo_getDataSpace}. If this
  *                  parameter is set to a different ADataSpace, AImageDecoder
  *                  will transform the output into the specified ADataSpace.
- * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or
- *         {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} for a null
- *         {@link AImageDecoder} or an integer that does not correspond to an
- *         {@link ADataSpace} value.
+ * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
+ *         indicating the reason for the failure.
+ *
+ * Errors:
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
+ *   {@link AImageDecoder} is null or |dataspace| does not correspond to an
+ *   {@link ADataSpace} value.
  */
 int AImageDecoder_setDataSpace(AImageDecoder*, int32_t dataspace) __INTRODUCED_IN(30);
 
@@ -236,11 +297,16 @@
  *              {@link AImageDecoder_getMinimumStride}, which will now return
  *              a value based on this width.
  * @param height Height of the output (prior to cropping).
- * @return an enum describing whether the call succeeded.
- * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or
- *         {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} if the {@link AImageDecoder}
- *         pointer is null, width or height is <= 0, or any existing crop is
- *         not contained by the new image dimensions.
+ * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
+ *         indicating the reason for the failure.
+ *
+ * Errors:
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
+ *   {@link AImageDecoder} is null.
+ * - {@link ANDROID_IMAGE_DECODER_INVALID_SCALE}: |width| or |height| is <= 0,
+ *   the size is too big, any existing crop is not contained by the new image dimensions,
+ *   or the scale is incompatible with a previous call to
+ *   {@link AImageDecoder_setUnpremultipliedRequired}(true).
  */
 int AImageDecoder_setTargetSize(AImageDecoder*, int32_t width, int32_t height) __INTRODUCED_IN(30);
 
@@ -262,8 +328,12 @@
  *              in the direction that the decoder can do most efficiently.
  * @param height Out parameter for the height sampled by sampleSize, and rounded
  *               in the direction that the decoder can do most efficiently.
- * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or
- *         {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} for bad input.
+ * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
+ *         indicating the reason for the failure.
+ *
+ * Errors:
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
+ *   {@link AImageDecoder}, |width| or |height| is null or |sampleSize| is < 1.
  */
 int AImageDecoder_computeSampledSize(const AImageDecoder*, int sampleSize,
                                      int32_t* width, int32_t* height) __INTRODUCED_IN(30);
@@ -282,18 +352,21 @@
  *             specifically { 0, 0, 0, 0 } - may be used to remove the cropping
  *             behavior. Any other empty or unsorted ARects will result in
  *             returning {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}.
- * @return an enum describing whether the call succeeded.
- * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or
- *         {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER} if the {@link AImageDecoder}
- *         pointer is null or the crop is not contained by the image
- *         dimensions.
+ * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
+ *         indicating the reason for the failure.
+ *
+ * Errors:
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The
+ *   {@link AImageDecoder} is null or the crop is not contained by the
+ *   (possibly scaled) image dimensions.
  */
 int AImageDecoder_setCrop(AImageDecoder*, ARect crop) __INTRODUCED_IN(30);
 
 struct AImageDecoderHeaderInfo;
 /**
- * Opaque handle for representing information about the encoded image. It can
- * be passed to methods like {@link AImageDecoderHeaderInfo_getWidth} and
+ * Opaque handle for representing information about the encoded image. Retrieved
+ * using {@link AImageDecoder_getHeaderInfo} and passed to methods like
+ * {@link AImageDecoderHeaderInfo_getWidth} and
  * {@link AImageDecoderHeaderInfo_getHeight}.
  */
 typedef struct AImageDecoderHeaderInfo AImageDecoderHeaderInfo;
@@ -310,14 +383,16 @@
 /**
  * Report the native width of the encoded image. This is also the logical
  * pixel width of the output, unless {@link AImageDecoder_setTargetSize} is
- * used to choose a different size.
+ * used to choose a different size or {@link AImageDecoder_setCrop} is used to
+ * set a crop rect.
  */
 int32_t AImageDecoderHeaderInfo_getWidth(const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30);
 
 /**
  * Report the native height of the encoded image. This is also the logical
  * pixel height of the output, unless {@link AImageDecoder_setTargetSize} is
- * used to choose a different size.
+ * used to choose a different size or {@link AImageDecoder_setCrop} is used to
+ * set a crop rect.
  */
 int32_t AImageDecoderHeaderInfo_getHeight(const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30);
 
@@ -349,20 +424,20 @@
         const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30);
 
 /**
- * Report the dataspace the {@link AImageDecoder} will decode to by default.
- * AImageDecoder will try to choose one that is sensible for the
- * image and the system. Note that this may not exactly match the ICC
- * profile (or other color information) stored in the encoded image.
+ * Report the dataspace the AImageDecoder will decode to by default.
  *
- * @return The {@link ADataSpace} most closely representing the way the colors
- *         are encoded (or {@link ADATASPACE_UNKNOWN} if there is not an
- *         approximate ADataSpace). This specifies how to interpret the colors
+ * By default, {@link AImageDecoder_decodeImage} will not do any color
+ * conversion.
+ *
+ * @return The {@link ADataSpace} representing the way the colors
+ *         are encoded (or {@link ADATASPACE_UNKNOWN} if there is not a
+ *         corresponding ADataSpace). This specifies how to interpret the colors
  *         in the decoded image, unless {@link AImageDecoder_setDataSpace} is
  *         called to decode to a different ADataSpace.
  *
  *         Note that ADataSpace only exposes a few values. This may return
- *         ADATASPACE_UNKNOWN, even for Named ColorSpaces, if they have no
- *         corresponding ADataSpace.
+ *         {@link ADATASPACE_UNKNOWN}, even for Named ColorSpaces, if they have
+ *         no corresponding {@link ADataSpace}.
  */
 int32_t AImageDecoderHeaderInfo_getDataSpace(
         const AImageDecoderHeaderInfo*) __INTRODUCED_IN(30);
@@ -392,11 +467,23 @@
  * @param size Size of the pixel buffer in bytes. Must be at least
  *             stride * (height - 1) +
  *             {@link AImageDecoder_getMinimumStride}.
- * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success, or an error code
- *         from the same enum describing the failure.
- *         {@link ANDROID_IMAGE_DECODER_INCOMPLETE} or
- *         {@link ANDROID_IMAGE_DECODER_ERROR} means that a partial image was
- *         decoded, and undecoded lines have been initialized to all zeroes.
+ * @return {@link ANDROID_IMAGE_DECODER_SUCCESS} on success or a value
+ *         indicating the reason for the failure.
+ *
+ * Errors:
+ * - {@link ANDROID_IMAGE_DECODER_INCOMPLETE}: The image was truncated. A
+ *   partial image was decoded, and undecoded lines have been initialized to all
+ *   zeroes.
+ * - {@link ANDROID_IMAGE_DECODER_ERROR}: The image contained an error. A
+ *   partial image was decoded, and undecoded lines have been initialized to all
+ *   zeroes.
+ * - {@link ANDROID_IMAGE_DECODER_BAD_PARAMETER}: The {@link AImageDecoder} or
+ *   |pixels| is null, the stride is not large enough or not pixel aligned, or
+ *   |size| is not large enough.
+ * - {@link ANDROID_IMAGE_DECODER_SEEK_ERROR}: The asset or file descriptor
+ *   failed to seek.
+ * - {@link ANDROID_IMAGE_DECODER_INTERNAL_ERROR}: Some other error, like a
+ *   failure to allocate memory.
  */
 int AImageDecoder_decodeImage(AImageDecoder* decoder,
                               void* pixels, size_t stride,
diff --git a/include/android/sensor.h b/include/android/sensor.h
index 12c00ad..e63ac4b 100644
--- a/include/android/sensor.h
+++ b/include/android/sensor.h
@@ -15,6 +15,9 @@
  */
 
 /**
+ * Structures and functions to receive and process sensor events in
+ * native code.
+ *
  * @addtogroup Sensor
  * @{
  */
@@ -42,12 +45,6 @@
  *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
  */
 
-/**
- * Structures and functions to receive and process sensor events in
- * native code.
- *
- */
-
 #include <android/looper.h>
 
 #include <stdbool.h>
diff --git a/include/ui/FatVector.h b/include/ui/FatVector.h
new file mode 120000
index 0000000..c2047c0
--- /dev/null
+++ b/include/ui/FatVector.h
@@ -0,0 +1 @@
+../../libs/ui/include/ui/FatVector.h
\ No newline at end of file
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 328653a..9888b59 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -85,31 +85,36 @@
     sp<AidlServiceManager> mTheRealServiceManager;
 };
 
-static Mutex gDefaultServiceManagerLock;
+static std::once_flag gSmOnce;
 static sp<IServiceManager> gDefaultServiceManager;
 
 sp<IServiceManager> defaultServiceManager()
 {
-
-    if (gDefaultServiceManager != nullptr) return gDefaultServiceManager;
-
-    {
-        AutoMutex _l(gDefaultServiceManagerLock);
-        while (gDefaultServiceManager == nullptr) {
-            gDefaultServiceManager = new ServiceManagerShim(
-                interface_cast<AidlServiceManager>(
-                    ProcessState::self()->getContextObject(nullptr)));
-            if (gDefaultServiceManager == nullptr)
+    std::call_once(gSmOnce, []() {
+        sp<AidlServiceManager> sm = nullptr;
+        while (sm == nullptr) {
+            sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
+            if (sm == nullptr) {
                 sleep(1);
+            }
         }
-    }
+
+        gDefaultServiceManager = new ServiceManagerShim(sm);
+    });
 
     return gDefaultServiceManager;
 }
 
 void setDefaultServiceManager(const sp<IServiceManager>& sm) {
-  AutoMutex _l(gDefaultServiceManagerLock);
-  gDefaultServiceManager = sm;
+    bool called = false;
+    std::call_once(gSmOnce, [&]() {
+        gDefaultServiceManager = sm;
+        called = true;
+    });
+
+    if (!called) {
+        LOG_ALWAYS_FATAL("setDefaultServiceManager() called after defaultServiceManager().");
+    }
 }
 
 #if !defined(__ANDROID_VNDK__) && defined(__ANDROID__)
diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h
index 31f022d..1d520c1 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -102,6 +102,9 @@
 
 /**
  * Directly set the default service manager. Only used for testing.
+ * Note that the caller is responsible for caling this method
+ * *before* any call to defaultServiceManager(); if the latter is
+ * called first, setDefaultServiceManager() will abort.
  */
 void setDefaultServiceManager(const sp<IServiceManager>& sm);
 
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index b40eb14..e184c7f 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -239,7 +239,7 @@
     ASSERT_EQ(&next, adapter.getNextTransaction());
 }
 
-TEST_F(BLASTBufferQueueTest, onFrameAvailable_ApplyDesiredPresentTime) {
+TEST_F(BLASTBufferQueueTest, DISABLED_onFrameAvailable_ApplyDesiredPresentTime) {
     BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
     sp<IGraphicBufferProducer> igbProducer;
     setUpProducer(adapter, igbProducer);
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index bf487c4..cd2a448 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -67,19 +67,20 @@
 // ----------------------------------------------------------------------------
 
 Region::Region() {
-    mStorage.add(Rect(0,0));
+    mStorage.push_back(Rect(0, 0));
 }
 
 Region::Region(const Region& rhs)
-    : mStorage(rhs.mStorage)
 {
+    mStorage.clear();
+    mStorage.insert(mStorage.begin(), rhs.mStorage.begin(), rhs.mStorage.end());
 #if defined(VALIDATE_REGIONS)
     validate(rhs, "rhs copy-ctor");
 #endif
 }
 
 Region::Region(const Rect& rhs) {
-    mStorage.add(rhs);
+    mStorage.push_back(rhs);
 }
 
 Region::~Region()
@@ -100,8 +101,8 @@
  * final, correctly ordered region buffer. Each rectangle will be compared with the span directly
  * above it, and subdivided to resolve any remaining T-junctions.
  */
-static void reverseRectsResolvingJunctions(const Rect* begin, const Rect* end,
-        Vector<Rect>& dst, int spanDirection) {
+static void reverseRectsResolvingJunctions(const Rect* begin, const Rect* end, FatVector<Rect>& dst,
+                                           int spanDirection) {
     dst.clear();
 
     const Rect* current = end - 1;
@@ -109,7 +110,7 @@
 
     // add first span immediately
     do {
-        dst.add(*current);
+        dst.push_back(*current);
         current--;
     } while (current->top == lastTop && current >= begin);
 
@@ -147,12 +148,12 @@
                 if (prev.right <= left) break;
 
                 if (prev.right > left && prev.right < right) {
-                    dst.add(Rect(prev.right, top, right, bottom));
+                    dst.push_back(Rect(prev.right, top, right, bottom));
                     right = prev.right;
                 }
 
                 if (prev.left > left && prev.left < right) {
-                    dst.add(Rect(prev.left, top, right, bottom));
+                    dst.push_back(Rect(prev.left, top, right, bottom));
                     right = prev.left;
                 }
 
@@ -166,12 +167,12 @@
                 if (prev.left >= right) break;
 
                 if (prev.left > left && prev.left < right) {
-                    dst.add(Rect(left, top, prev.left, bottom));
+                    dst.push_back(Rect(left, top, prev.left, bottom));
                     left = prev.left;
                 }
 
                 if (prev.right > left && prev.right < right) {
-                    dst.add(Rect(left, top, prev.right, bottom));
+                    dst.push_back(Rect(left, top, prev.right, bottom));
                     left = prev.right;
                 }
                 // if an entry in the previous span is too far left, nothing further right in the
@@ -183,7 +184,7 @@
         }
 
         if (left < right) {
-            dst.add(Rect(left, top, right, bottom));
+            dst.push_back(Rect(left, top, right, bottom));
         }
 
         current--;
@@ -201,13 +202,14 @@
     if (r.isEmpty()) return r;
     if (r.isRect()) return r;
 
-    Vector<Rect> reversed;
+    FatVector<Rect> reversed;
     reverseRectsResolvingJunctions(r.begin(), r.end(), reversed, direction_RTL);
 
     Region outputRegion;
-    reverseRectsResolvingJunctions(reversed.begin(), reversed.end(),
-            outputRegion.mStorage, direction_LTR);
-    outputRegion.mStorage.add(r.getBounds()); // to make region valid, mStorage must end with bounds
+    reverseRectsResolvingJunctions(reversed.data(), reversed.data() + reversed.size(),
+                                   outputRegion.mStorage, direction_LTR);
+    outputRegion.mStorage.push_back(
+            r.getBounds()); // to make region valid, mStorage must end with bounds
 
 #if defined(VALIDATE_REGIONS)
     validate(outputRegion, "T-Junction free region");
@@ -222,7 +224,8 @@
     validate(*this, "this->operator=");
     validate(rhs, "rhs.operator=");
 #endif
-    mStorage = rhs.mStorage;
+    mStorage.clear();
+    mStorage.insert(mStorage.begin(), rhs.mStorage.begin(), rhs.mStorage.end());
     return *this;
 }
 
@@ -231,7 +234,7 @@
     if (mStorage.size() >= 2) {
         const Rect bounds(getBounds());
         mStorage.clear();
-        mStorage.add(bounds);
+        mStorage.push_back(bounds);
     }
     return *this;
 }
@@ -255,25 +258,25 @@
 void Region::clear()
 {
     mStorage.clear();
-    mStorage.add(Rect(0,0));
+    mStorage.push_back(Rect(0, 0));
 }
 
 void Region::set(const Rect& r)
 {
     mStorage.clear();
-    mStorage.add(r);
+    mStorage.push_back(r);
 }
 
 void Region::set(int32_t w, int32_t h)
 {
     mStorage.clear();
-    mStorage.add(Rect(w, h));
+    mStorage.push_back(Rect(w, h));
 }
 
 void Region::set(uint32_t w, uint32_t h)
 {
     mStorage.clear();
-    mStorage.add(Rect(w, h));
+    mStorage.push_back(Rect(w, h));
 }
 
 bool Region::isTriviallyEqual(const Region& region) const {
@@ -299,8 +302,7 @@
 void Region::addRectUnchecked(int l, int t, int r, int b)
 {
     Rect rect(l,t,r,b);
-    size_t where = mStorage.size() - 1;
-    mStorage.insertAt(rect, where, 1);
+    mStorage.insert(mStorage.end() - 1, rect);
 }
 
 // ----------------------------------------------------------------------------
@@ -350,7 +352,7 @@
 
 Region& Region::scaleSelf(float sx, float sy) {
     size_t count = mStorage.size();
-    Rect* rects = mStorage.editArray();
+    Rect* rects = mStorage.data();
     while (count) {
         rects->left = static_cast<int32_t>(static_cast<float>(rects->left) * sx + 0.5f);
         rects->right = static_cast<int32_t>(static_cast<float>(rects->right) * sx + 0.5f);
@@ -455,10 +457,10 @@
 class Region::rasterizer : public region_operator<Rect>::region_rasterizer
 {
     Rect bounds;
-    Vector<Rect>& storage;
+    FatVector<Rect>& storage;
     Rect* head;
     Rect* tail;
-    Vector<Rect> span;
+    FatVector<Rect> span;
     Rect* cur;
 public:
     explicit rasterizer(Region& reg)
@@ -485,8 +487,8 @@
         flushSpan();
     }
     if (storage.size()) {
-        bounds.top = storage.itemAt(0).top;
-        bounds.bottom = storage.top().bottom;
+        bounds.top = storage.front().top;
+        bounds.bottom = storage.back().bottom;
         if (storage.size() == 1) {
             storage.clear();
         }
@@ -494,7 +496,7 @@
         bounds.left  = 0;
         bounds.right = 0;
     }
-    storage.add(bounds);
+    storage.push_back(bounds);
 }
 
 void Region::rasterizer::operator()(const Rect& rect)
@@ -509,15 +511,15 @@
             return;
         }
     }
-    span.add(rect);
-    cur = span.editArray() + (span.size() - 1);
+    span.push_back(rect);
+    cur = span.data() + (span.size() - 1);
 }
 
 void Region::rasterizer::flushSpan()
 {
     bool merge = false;
     if (tail-head == ssize_t(span.size())) {
-        Rect const* p = span.editArray();
+        Rect const* p = span.data();
         Rect const* q = head;
         if (p->top == q->bottom) {
             merge = true;
@@ -532,17 +534,17 @@
         }
     }
     if (merge) {
-        const int bottom = span[0].bottom;
+        const int bottom = span.front().bottom;
         Rect* r = head;
         while (r != tail) {
             r->bottom = bottom;
             r++;
         }
     } else {
-        bounds.left = min(span.itemAt(0).left, bounds.left);
-        bounds.right = max(span.top().right, bounds.right);
-        storage.appendVector(span);
-        tail = storage.editArray() + storage.size();
+        bounds.left = min(span.front().left, bounds.left);
+        bounds.right = max(span.back().right, bounds.right);
+        storage.insert(storage.end(), span.begin(), span.end());
+        tail = storage.data() + storage.size();
         head = tail - span.size();
     }
     span.clear();
@@ -550,7 +552,7 @@
 
 bool Region::validate(const Region& reg, const char* name, bool silent)
 {
-    if (reg.mStorage.isEmpty()) {
+    if (reg.mStorage.empty()) {
         ALOGE_IF(!silent, "%s: mStorage is empty, which is never valid", name);
         // return immediately as the code below assumes mStorage is non-empty
         return false;
@@ -689,9 +691,8 @@
     }
     sk_dst.op(sk_lhs, sk_rhs, sk_op);
 
-    if (sk_dst.isEmpty() && dst.isEmpty())
-        return;
-    
+    if (sk_dst.empty() && dst.empty()) return;
+
     bool same = true;
     Region::const_iterator head = dst.begin();
     Region::const_iterator const tail = dst.end();
@@ -786,7 +787,7 @@
         validate(reg, "translate (before)");
 #endif
         size_t count = reg.mStorage.size();
-        Rect* rects = reg.mStorage.editArray();
+        Rect* rects = reg.mStorage.data();
         while (count) {
             rects->offsetBy(dx, dy);
             rects++;
@@ -866,24 +867,25 @@
         ALOGE("Region::unflatten() failed, invalid region");
         return BAD_VALUE;
     }
-    mStorage = result.mStorage;
+    mStorage.clear();
+    mStorage.insert(mStorage.begin(), result.mStorage.begin(), result.mStorage.end());
     return NO_ERROR;
 }
 
 // ----------------------------------------------------------------------------
 
 Region::const_iterator Region::begin() const {
-    return mStorage.array();
+    return mStorage.data();
 }
 
 Region::const_iterator Region::end() const {
     // Workaround for b/77643177
     // mStorage should never be empty, but somehow it is and it's causing
     // an abort in ubsan
-    if (mStorage.isEmpty()) return mStorage.array();
+    if (mStorage.empty()) return mStorage.data();
 
     size_t numRects = isRect() ? 1 : mStorage.size() - 1;
-    return mStorage.array() + numRects;
+    return mStorage.data() + numRects;
 }
 
 Rect const* Region::getArray(size_t* count) const {
diff --git a/libs/ui/include/ui/FatVector.h b/libs/ui/include/ui/FatVector.h
new file mode 100644
index 0000000..25fe3a0
--- /dev/null
+++ b/libs/ui/include/ui/FatVector.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2019, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_REGION_FAT_VECTOR_H
+#define ANDROID_REGION_FAT_VECTOR_H
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <utils/Log.h>
+#include <type_traits>
+
+#include <vector>
+
+namespace android {
+
+template <typename T, size_t SIZE = 4>
+class InlineStdAllocator {
+public:
+    struct Allocation {
+    private:
+        Allocation(const Allocation&) = delete;
+        void operator=(const Allocation&) = delete;
+
+    public:
+        Allocation() {}
+        // char array instead of T array, so memory is uninitialized, with no destructors run
+        char array[sizeof(T) * SIZE];
+        bool inUse = false;
+    };
+
+    typedef T value_type; // needed to implement std::allocator
+    typedef T* pointer;   // needed to implement std::allocator
+
+    explicit InlineStdAllocator(Allocation& allocation) : mAllocation(allocation) {}
+    InlineStdAllocator(const InlineStdAllocator& other) : mAllocation(other.mAllocation) {}
+    ~InlineStdAllocator() {}
+
+    T* allocate(size_t num, const void* = 0) {
+        if (!mAllocation.inUse && num <= SIZE) {
+            mAllocation.inUse = true;
+            return static_cast<T*>(static_cast<void*>(mAllocation.array));
+        } else {
+            return static_cast<T*>(static_cast<void*>(malloc(num * sizeof(T))));
+        }
+    }
+
+    void deallocate(pointer p, size_t) {
+        if (p == static_cast<T*>(static_cast<void*>(mAllocation.array))) {
+            mAllocation.inUse = false;
+        } else {
+            // 'free' instead of delete here - destruction handled separately
+            free(p);
+        }
+    }
+    Allocation& mAllocation;
+};
+
+/**
+ * std::vector with SIZE elements preallocated into an internal buffer.
+ *
+ * Useful for avoiding the cost of malloc in cases where only SIZE or
+ * fewer elements are needed in the common case.
+ */
+template <typename T, size_t SIZE = 4>
+class FatVector : public std::vector<T, InlineStdAllocator<T, SIZE>> {
+public:
+    FatVector()
+          : std::vector<T, InlineStdAllocator<T, SIZE>>(InlineStdAllocator<T, SIZE>(mAllocation)) {
+        this->reserve(SIZE);
+    }
+
+    explicit FatVector(size_t capacity) : FatVector() { this->resize(capacity); }
+
+private:
+    typename InlineStdAllocator<T, SIZE>::Allocation mAllocation;
+};
+
+} // namespace android
+
+#endif // ANDROID_REGION_FAT_VECTOR_H
diff --git a/libs/ui/include/ui/Region.h b/libs/ui/include/ui/Region.h
index 2db3b10..6bb7b8d 100644
--- a/libs/ui/include/ui/Region.h
+++ b/libs/ui/include/ui/Region.h
@@ -21,13 +21,13 @@
 #include <sys/types.h>
 #include <ostream>
 
-#include <utils/Vector.h>
-
 #include <ui/Rect.h>
 #include <utils/Flattenable.h>
 
 #include <android-base/macros.h>
 
+#include "FatVector.h"
+
 #include <string>
 
 namespace android {
@@ -180,7 +180,7 @@
     // with an extra Rect as the last element which is set to the
     // bounds of the region. However, if the region is
     // a simple Rect then mStorage contains only that rect.
-    Vector<Rect> mStorage;
+    FatVector<Rect> mStorage;
 };
 
 
@@ -235,4 +235,3 @@
 }; // namespace android
 
 #endif // ANDROID_UI_REGION_H
-
diff --git a/libs/ui/include_vndk/ui/FatVector.h b/libs/ui/include_vndk/ui/FatVector.h
new file mode 120000
index 0000000..bf30166
--- /dev/null
+++ b/libs/ui/include_vndk/ui/FatVector.h
@@ -0,0 +1 @@
+../../include/ui/FatVector.h
\ No newline at end of file
diff --git a/services/automotive/display/Android.bp b/services/automotive/display/Android.bp
index 5a5dc89..d94fb27 100644
--- a/services/automotive/display/Android.bp
+++ b/services/automotive/display/Android.bp
@@ -18,8 +18,8 @@
     name: "android.frameworks.automotive.display@1.0-service",
     defaults: ["hidl_defaults"],
     srcs: [
-        "main_automotivedisplay.cpp",
-        "CarWindowService.cpp",
+        "main_automotivedisplayproxy.cpp",
+        "AutomotiveDisplayProxyService.cpp",
     ],
     init_rc: ["android.frameworks.automotive.display@1.0-service.rc"],
 
diff --git a/services/automotive/display/CarWindowService.cpp b/services/automotive/display/AutomotiveDisplayProxyService.cpp
similarity index 94%
rename from services/automotive/display/CarWindowService.cpp
rename to services/automotive/display/AutomotiveDisplayProxyService.cpp
index 09ae34a..3cd8e39 100644
--- a/services/automotive/display/CarWindowService.cpp
+++ b/services/automotive/display/AutomotiveDisplayProxyService.cpp
@@ -18,7 +18,7 @@
 
 #include <gui/bufferqueue/2.0/B2HGraphicBufferProducer.h>
 
-#include "CarWindowService.h"
+#include "AutomotiveDisplayProxyService.h"
 
 namespace android {
 namespace frameworks {
@@ -28,7 +28,7 @@
 namespace implementation {
 
 Return<sp<IGraphicBufferProducer>>
-    CarWindowService::getIGraphicBufferProducer() {
+AutomotiveDisplayProxyService::getIGraphicBufferProducer() {
     if (mSurface == nullptr) {
         status_t err;
         mSurfaceComposerClient = new SurfaceComposerClient();
@@ -86,7 +86,7 @@
                         mSurface->getIGraphicBufferProducer());
 }
 
-Return<bool> CarWindowService::showWindow() {
+Return<bool> AutomotiveDisplayProxyService::showWindow() {
     status_t status = NO_ERROR;
 
     if (mSurfaceControl != nullptr) {
@@ -103,7 +103,7 @@
     return status == NO_ERROR;
 }
 
-Return<bool> CarWindowService::hideWindow() {
+Return<bool> AutomotiveDisplayProxyService::hideWindow() {
     status_t status = NO_ERROR;
 
     if (mSurfaceControl != nullptr) {
diff --git a/services/automotive/display/include/CarWindowService.h b/services/automotive/display/include/AutomotiveDisplayProxyService.h
similarity index 92%
rename from services/automotive/display/include/CarWindowService.h
rename to services/automotive/display/include/AutomotiveDisplayProxyService.h
index a32ed7c..3956602 100644
--- a/services/automotive/display/include/CarWindowService.h
+++ b/services/automotive/display/include/AutomotiveDisplayProxyService.h
@@ -15,7 +15,7 @@
 //
 #pragma once
 
-#include <android/frameworks/automotive/display/1.0/ICarWindowService.h>
+#include <android/frameworks/automotive/display/1.0/IAutomotiveDisplayProxyService.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/Surface.h>
@@ -34,7 +34,7 @@
 using ::android::sp;
 using ::android::hardware::graphics::bufferqueue::V2_0::IGraphicBufferProducer;
 
-class CarWindowService : public ICarWindowService {
+class AutomotiveDisplayProxyService : public IAutomotiveDisplayProxyService {
 public:
     Return<sp<IGraphicBufferProducer>> getIGraphicBufferProducer() override;
     Return<bool> showWindow() override;
diff --git a/services/automotive/display/main_automotivedisplay.cpp b/services/automotive/display/main_automotivedisplayproxy.cpp
similarity index 88%
rename from services/automotive/display/main_automotivedisplay.cpp
rename to services/automotive/display/main_automotivedisplayproxy.cpp
index 69f0a13..626c185 100644
--- a/services/automotive/display/main_automotivedisplay.cpp
+++ b/services/automotive/display/main_automotivedisplayproxy.cpp
@@ -23,14 +23,14 @@
 #include <utils/Errors.h>
 #include <utils/StrongPointer.h>
 
-#include "CarWindowService.h"
+#include "AutomotiveDisplayProxyService.h"
 
 // libhidl:
 using android::hardware::configureRpcThreadpool;
 using android::hardware::joinRpcThreadpool;
 
 // Generated HIDL files
-using android::frameworks::automotive::display::V1_0::ICarWindowService;
+using android::frameworks::automotive::display::V1_0::IAutomotiveDisplayProxyService;
 
 // The namespace in which all our implementation code lives
 using namespace android::frameworks::automotive::display::V1_0::implementation;
@@ -41,7 +41,7 @@
 int main() {
     ALOGI("Car Window Service is starting");
 
-    android::sp<ICarWindowService> service = new CarWindowService();
+    android::sp<IAutomotiveDisplayProxyService> service = new AutomotiveDisplayProxyService();
 
     configureRpcThreadpool(1, true /* callerWillJoin */);
 
diff --git a/services/inputflinger/reader/mapper/TouchInputMapper.cpp b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
index b66caca..3b20173 100644
--- a/services/inputflinger/reader/mapper/TouchInputMapper.cpp
+++ b/services/inputflinger/reader/mapper/TouchInputMapper.cpp
@@ -761,7 +761,11 @@
         (mDeviceMode == DEVICE_MODE_DIRECT && mConfig.showTouches)) {
         if (mPointerController == nullptr || viewportChanged) {
             mPointerController = getPolicy()->obtainPointerController(getDeviceId());
-            mPointerController->setDisplayViewport(mViewport);
+            // Set the DisplayViewport for the PointerController to the default pointer display
+            // that is recommended by the configuration before using it.
+            std::optional<DisplayViewport> defaultViewport =
+                    mConfig.getDisplayViewportById(mConfig.defaultPointerDisplayId);
+            mPointerController->setDisplayViewport(defaultViewport.value_or(mViewport));
         }
     } else {
         mPointerController.clear();
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index e803c9a..914a4cb 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -520,6 +520,10 @@
 status_t SensorService::dumpProtoLocked(int fd, ConnectionSafeAutolock* connLock) const {
     using namespace service::SensorServiceProto;
     util::ProtoOutputStream proto;
+    proto.write(INIT_STATUS, int(SensorDevice::getInstance().initCheck()));
+    if (!mSensors.hasAnySensor()) {
+        return proto.flush(fd) ? OK : UNKNOWN_ERROR;
+    }
     const bool privileged = IPCThreadState::self()->getCallingUid() == 0;
 
     timespec curTime;
diff --git a/services/stats/Android.bp b/services/stats/Android.bp
new file mode 100644
index 0000000..1ce0524
--- /dev/null
+++ b/services/stats/Android.bp
@@ -0,0 +1,22 @@
+cc_library_shared {
+    name: "libstatshidl",
+    srcs: [
+        "StatsHal.cpp",
+    ],
+    cflags: ["-Wall", "-Werror"],
+    shared_libs: [
+        "android.frameworks.stats@1.0",
+        "libhidlbase",
+        "liblog",
+        "libstatslog",
+        "libstatssocket",
+        "libutils",
+    ],
+    export_include_dirs: [
+    	"include/",
+    ],
+    local_include_dirs: [
+        "include/stats",
+    ],
+    vintf_fragments: ["android.frameworks.stats@1.0-service.xml"]
+}
diff --git a/services/stats/OWNERS b/services/stats/OWNERS
new file mode 100644
index 0000000..a61babf
--- /dev/null
+++ b/services/stats/OWNERS
@@ -0,0 +1,9 @@
+jeffreyhuang@google.com
+joeo@google.com
+jtnguyen@google.com
+muhammadq@google.com
+ruchirr@google.com
+singhtejinder@google.com
+tsaichristine@google.com
+yaochen@google.com
+yro@google.com
diff --git a/services/stats/StatsHal.cpp b/services/stats/StatsHal.cpp
new file mode 100644
index 0000000..80c3b65
--- /dev/null
+++ b/services/stats/StatsHal.cpp
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define DEBUG false // STOPSHIP if true
+#define LOG_TAG "StatsHal"
+
+#include <log/log.h>
+#include <statslog.h>
+
+#include "StatsHal.h"
+
+namespace android {
+namespace frameworks {
+namespace stats {
+namespace V1_0 {
+namespace implementation {
+
+StatsHal::StatsHal() {}
+
+hardware::Return<void> StatsHal::reportSpeakerImpedance(
+        const SpeakerImpedance& speakerImpedance) {
+    android::util::stats_write(android::util::SPEAKER_IMPEDANCE_REPORTED,
+            speakerImpedance.speakerLocation, speakerImpedance.milliOhms);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsHal::reportHardwareFailed(const HardwareFailed& hardwareFailed) {
+    android::util::stats_write(android::util::HARDWARE_FAILED, int32_t(hardwareFailed.hardwareType),
+            hardwareFailed.hardwareLocation, int32_t(hardwareFailed.errorCode));
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsHal::reportPhysicalDropDetected(
+        const PhysicalDropDetected& physicalDropDetected) {
+    android::util::stats_write(android::util::PHYSICAL_DROP_DETECTED,
+            int32_t(physicalDropDetected.confidencePctg), physicalDropDetected.accelPeak,
+            physicalDropDetected.freefallDuration);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsHal::reportChargeCycles(const ChargeCycles& chargeCycles) {
+    std::vector<int32_t> buckets = chargeCycles.cycleBucket;
+    int initialSize = buckets.size();
+    for (int i = 0; i < 10 - initialSize; i++) {
+        buckets.push_back(-1); // Push -1 for buckets that do not exist.
+    }
+    android::util::stats_write(android::util::CHARGE_CYCLES_REPORTED, buckets[0], buckets[1],
+            buckets[2], buckets[3], buckets[4], buckets[5], buckets[6], buckets[7], buckets[8],
+            buckets[9]);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsHal::reportBatteryHealthSnapshot(
+        const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) {
+    android::util::stats_write(android::util::BATTERY_HEALTH_SNAPSHOT,
+            int32_t(batteryHealthSnapshotArgs.type), batteryHealthSnapshotArgs.temperatureDeciC,
+            batteryHealthSnapshotArgs.voltageMicroV, batteryHealthSnapshotArgs.currentMicroA,
+            batteryHealthSnapshotArgs.openCircuitVoltageMicroV,
+            batteryHealthSnapshotArgs.resistanceMicroOhm, batteryHealthSnapshotArgs.levelPercent);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsHal::reportSlowIo(const SlowIo& slowIo) {
+    android::util::stats_write(android::util::SLOW_IO, int32_t(slowIo.operation), slowIo.count);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsHal::reportBatteryCausedShutdown(
+        const BatteryCausedShutdown& batteryCausedShutdown) {
+    android::util::stats_write(android::util::BATTERY_CAUSED_SHUTDOWN,
+            batteryCausedShutdown.voltageMicroV);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsHal::reportUsbPortOverheatEvent(
+        const UsbPortOverheatEvent& usbPortOverheatEvent) {
+    android::util::stats_write(android::util::USB_PORT_OVERHEAT_EVENT_REPORTED,
+            usbPortOverheatEvent.plugTemperatureDeciC, usbPortOverheatEvent.maxTemperatureDeciC,
+            usbPortOverheatEvent.timeToOverheat, usbPortOverheatEvent.timeToHysteresis,
+            usbPortOverheatEvent.timeToInactive);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsHal::reportSpeechDspStat(
+        const SpeechDspStat& speechDspStat) {
+    android::util::stats_write(android::util::SPEECH_DSP_STAT_REPORTED,
+            speechDspStat.totalUptimeMillis, speechDspStat.totalDowntimeMillis,
+            speechDspStat.totalCrashCount, speechDspStat.totalRecoverCount);
+
+    return hardware::Void();
+}
+
+hardware::Return<void> StatsHal::reportVendorAtom(const VendorAtom& vendorAtom) {
+    std::string reverseDomainName = (std::string) vendorAtom.reverseDomainName;
+    if (vendorAtom.atomId < 100000 || vendorAtom.atomId >= 200000) {
+        ALOGE("Atom ID %ld is not a valid vendor atom ID", (long) vendorAtom.atomId);
+        return hardware::Void();
+    }
+    if (reverseDomainName.length() > 50) {
+        ALOGE("Vendor atom reverse domain name %s is too long.", reverseDomainName.c_str());
+        return hardware::Void();
+    }
+    AStatsEvent* event = AStatsEvent_obtain();
+    AStatsEvent_setAtomId(event, vendorAtom.atomId);
+    AStatsEvent_writeString(event, vendorAtom.reverseDomainName.c_str());
+    for (int i = 0; i < (int)vendorAtom.values.size(); i++) {
+        switch (vendorAtom.values[i].getDiscriminator()) {
+            case VendorAtom::Value::hidl_discriminator::intValue:
+                AStatsEvent_writeInt32(event, vendorAtom.values[i].intValue());
+                break;
+            case VendorAtom::Value::hidl_discriminator::longValue:
+                AStatsEvent_writeInt64(event, vendorAtom.values[i].longValue());
+                break;
+            case VendorAtom::Value::hidl_discriminator::floatValue:
+                AStatsEvent_writeFloat(event, vendorAtom.values[i].floatValue());
+                break;
+            case VendorAtom::Value::hidl_discriminator::stringValue:
+                AStatsEvent_writeString(event, vendorAtom.values[i].stringValue().c_str());
+                break;
+        }
+    }
+    AStatsEvent_build(event);
+    AStatsEvent_write(event);
+    AStatsEvent_release(event);
+
+    return hardware::Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace stats
+}  // namespace frameworks
+}  // namespace android
diff --git a/services/stats/android.frameworks.stats@1.0-service.xml b/services/stats/android.frameworks.stats@1.0-service.xml
new file mode 100644
index 0000000..bb02f66
--- /dev/null
+++ b/services/stats/android.frameworks.stats@1.0-service.xml
@@ -0,0 +1,11 @@
+<manifest version="1.0" type="framework">
+    <hal>
+        <name>android.frameworks.stats</name>
+        <transport>hwbinder</transport>
+        <version>1.0</version>
+        <interface>
+            <name>IStats</name>
+            <instance>default</instance>
+        </interface>
+    </hal>
+</manifest>
diff --git a/services/stats/include/stats/StatsHal.h b/services/stats/include/stats/StatsHal.h
new file mode 100644
index 0000000..071e54f
--- /dev/null
+++ b/services/stats/include/stats/StatsHal.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/frameworks/stats/1.0/IStats.h>
+#include <android/frameworks/stats/1.0/types.h>
+
+#include <stats_event.h>
+
+using namespace android::frameworks::stats::V1_0;
+
+namespace android {
+namespace frameworks {
+namespace stats {
+namespace V1_0 {
+namespace implementation {
+
+using android::hardware::Return;
+
+/**
+* Implements the Stats HAL
+*/
+class StatsHal : public IStats {
+public:
+    StatsHal();
+
+    /**
+     * Binder call to get SpeakerImpedance atom.
+     */
+    virtual Return<void> reportSpeakerImpedance(const SpeakerImpedance& speakerImpedance) override;
+
+    /**
+     * Binder call to get HardwareFailed atom.
+     */
+    virtual Return<void> reportHardwareFailed(const HardwareFailed& hardwareFailed) override;
+
+    /**
+     * Binder call to get PhysicalDropDetected atom.
+     */
+    virtual Return<void> reportPhysicalDropDetected(
+             const PhysicalDropDetected& physicalDropDetected) override;
+
+    /**
+     * Binder call to get ChargeCyclesReported atom.
+     */
+     virtual Return<void> reportChargeCycles(const ChargeCycles& chargeCycles) override;
+
+    /**
+     * Binder call to get BatteryHealthSnapshot atom.
+     */
+    virtual Return<void> reportBatteryHealthSnapshot(
+            const BatteryHealthSnapshotArgs& batteryHealthSnapshotArgs) override;
+
+    /**
+     * Binder call to get SlowIo atom.
+     */
+    virtual Return<void> reportSlowIo(const SlowIo& slowIo) override;
+
+    /**
+     * Binder call to get BatteryCausedShutdown atom.
+     */
+    virtual Return<void> reportBatteryCausedShutdown(
+            const BatteryCausedShutdown& batteryCausedShutdown) override;
+
+    /**
+     * Binder call to get UsbPortOverheatEvent atom.
+     */
+    virtual Return<void> reportUsbPortOverheatEvent(
+            const UsbPortOverheatEvent& usbPortOverheatEvent) override;
+
+    /**
+     * Binder call to get Speech DSP state atom.
+     */
+    virtual Return<void> reportSpeechDspStat(
+            const SpeechDspStat& speechDspStat) override;
+
+    /**
+     * Binder call to get vendor atom.
+     */
+    virtual Return<void> reportVendorAtom(const VendorAtom& vendorAtom) override;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace stats
+}  // namespace frameworks
+}  // namespace android
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index 3cc803e..e65064b 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -441,6 +441,7 @@
             status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500));
             if (result != NO_ERROR) {
                 ALOGE("[%s] Timed out waiting on callback", getDebugName());
+                break;
             }
         }
 
@@ -469,6 +470,7 @@
             status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500));
             if (result != NO_ERROR) {
                 ALOGE("[%s] Timed out waiting on callback", getDebugName());
+                break;
             }
         }
 
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index c73e825..8202515 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -229,6 +229,15 @@
     return *mCurrentRefreshRate;
 }
 
+const RefreshRate& RefreshRateConfigs::getCurrentRefreshRateByPolicy() const {
+    std::lock_guard lock(mLock);
+    if (std::find(mAvailableRefreshRates.begin(), mAvailableRefreshRates.end(),
+                  mCurrentRefreshRate) != mAvailableRefreshRates.end()) {
+        return *mCurrentRefreshRate;
+    }
+    return mRefreshRates.at(mDefaultConfig);
+}
+
 void RefreshRateConfigs::setCurrentConfigId(HwcConfigIndexType configId) {
     std::lock_guard lock(mLock);
     mCurrentRefreshRate = &mRefreshRates.at(configId);
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index fc95959..e5bb557 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -149,6 +149,10 @@
     // Returns the current refresh rate
     const RefreshRate& getCurrentRefreshRate() const EXCLUDES(mLock);
 
+    // Returns the current refresh rate, if allowed. Otherwise the default that is allowed by
+    // the policy.
+    const RefreshRate& getCurrentRefreshRateByPolicy() const;
+
     // Returns the refresh rate that corresponds to a HwcConfigIndexType. This won't change at
     // runtime.
     const RefreshRate& getRefreshRateFromConfigId(HwcConfigIndexType configId) const {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 49a269f..94791eb 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -108,7 +108,8 @@
         mUseContentDetectionV2(useContentDetectionV2) {
     using namespace sysprop;
 
-    if (property_get_bool("debug.sf.use_smart_90_for_video", 0) || use_smart_90_for_video(false)) {
+    if (property_get_bool("debug.sf.use_content_detection_for_refresh_rate", 0) ||
+        use_content_detection_for_refresh_rate(false)) {
         if (mUseContentDetectionV2) {
             mLayerHistory = std::make_unique<scheduler::impl::LayerHistoryV2>();
         } else {
@@ -624,8 +625,8 @@
                 .configId;
     }
 
-    // There are no signals for refresh rate, just leave it as is
-    return mRefreshRateConfigs.getCurrentRefreshRate().configId;
+    // There are no signals for refresh rate, just leave it as is.
+    return mRefreshRateConfigs.getCurrentRefreshRateByPolicy().configId;
 }
 
 std::optional<HwcConfigIndexType> Scheduler::getPreferredConfigId() {
diff --git a/services/surfaceflinger/SurfaceFlingerProperties.cpp b/services/surfaceflinger/SurfaceFlingerProperties.cpp
index e199b53..269cf94 100644
--- a/services/surfaceflinger/SurfaceFlingerProperties.cpp
+++ b/services/surfaceflinger/SurfaceFlingerProperties.cpp
@@ -18,6 +18,7 @@
 #include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
 #include <android/hardware/configstore/1.1/types.h>
 #include <configstore/Utils.h>
+#include <utils/Log.h>
 
 #include <log/log.h>
 #include <cstdlib>
@@ -263,8 +264,17 @@
     return defaultValue;
 }
 
-bool use_smart_90_for_video(bool defaultValue) {
-    auto temp = SurfaceFlingerProperties::use_smart_90_for_video();
+bool use_content_detection_for_refresh_rate(bool defaultValue) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+    auto smart_90_deprecated = SurfaceFlingerProperties::use_smart_90_for_video();
+#pragma clang diagnostic pop
+    if (smart_90_deprecated.has_value()) {
+        ALOGW("Using deprecated use_smart_90_for_video sysprop. Value: %d", *smart_90_deprecated);
+        return *smart_90_deprecated;
+    }
+
+    auto temp = SurfaceFlingerProperties::use_content_detection_for_refresh_rate();
     if (temp.has_value()) {
         return *temp;
     }
diff --git a/services/surfaceflinger/SurfaceFlingerProperties.h b/services/surfaceflinger/SurfaceFlingerProperties.h
index e394cca..440df49 100644
--- a/services/surfaceflinger/SurfaceFlingerProperties.h
+++ b/services/surfaceflinger/SurfaceFlingerProperties.h
@@ -81,7 +81,7 @@
 
 int32_t set_display_power_timer_ms(int32_t defaultValue);
 
-bool use_smart_90_for_video(bool defaultValue);
+bool use_content_detection_for_refresh_rate(bool defaultValue);
 
 bool enable_protected_contents(bool defaultValue);
 
diff --git a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
index 764181a..71f8d6a 100644
--- a/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
+++ b/services/surfaceflinger/sysprop/SurfaceFlingerProperties.sysprop
@@ -345,14 +345,26 @@
     prop_name: "ro.surface_flinger.set_display_power_timer_ms"
 }
 
+# useContentDetectionForRefreshRate indicates whether Scheduler should detect content FPS, and try
+# to adjust the screen refresh rate based on that.
+prop {
+    api_name: "use_content_detection_for_refresh_rate"
+    type: Boolean
+    scope: Public
+    access: Readonly
+    prop_name: "ro.surface_flinger.use_content_detection_for_refresh_rate"
+}
+
 # useSmart90ForVideo indicates whether Scheduler should detect content FPS, and try to adjust the
 # screen refresh rate based on that.
+# Replaced by useContentDetectionForRefreshRate
 prop {
     api_name: "use_smart_90_for_video"
     type: Boolean
     scope: Public
     access: Readonly
     prop_name: "ro.surface_flinger.use_smart_90_for_video"
+    deprecated: true
 }
 
 prop {
diff --git a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
index bee99f4..cdfd0f5 100644
--- a/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
+++ b/services/surfaceflinger/sysprop/api/SurfaceFlingerProperties-current.txt
@@ -113,12 +113,17 @@
     prop_name: "ro.surface_flinger.use_color_management"
   }
   prop {
+    api_name: "use_content_detection_for_refresh_rate"
+    prop_name: "ro.surface_flinger.use_content_detection_for_refresh_rate"
+  }
+  prop {
     api_name: "use_context_priority"
     prop_name: "ro.surface_flinger.use_context_priority"
   }
   prop {
     api_name: "use_smart_90_for_video"
     prop_name: "ro.surface_flinger.use_smart_90_for_video"
+    deprecated: true
   }
   prop {
     api_name: "use_vr_flinger"