Merge "Revert "Revert "Add useVrFlinger() method to SurfaceFlinger ConfigStore"""
diff --git a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
index b106481..5b00675 100644
--- a/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
+++ b/biometrics/fingerprint/2.1/default/BiometricsFingerprint.cpp
@@ -264,27 +264,35 @@
         case FINGERPRINT_ERROR: {
                 int32_t vendorCode = 0;
                 FingerprintError result = VendorErrorFilter(msg->data.error, &vendorCode);
-                thisPtr->mClientCallback->onError(devId, result, vendorCode);
+                if (!thisPtr->mClientCallback->onError(devId, result, vendorCode).isOk()) {
+                    ALOGE("failed to invoke fingerprint onError callback");
+                }
             }
             break;
         case FINGERPRINT_ACQUIRED: {
                 int32_t vendorCode = 0;
                 FingerprintAcquiredInfo result =
                     VendorAcquiredFilter(msg->data.acquired.acquired_info, &vendorCode);
-                thisPtr->mClientCallback->onAcquired(devId, result, vendorCode);
+                if (!thisPtr->mClientCallback->onAcquired(devId, result, vendorCode).isOk()) {
+                    ALOGE("failed to invoke fingerprint onAcquired callback");
+                }
             }
             break;
         case FINGERPRINT_TEMPLATE_ENROLLING:
-            thisPtr->mClientCallback->onEnrollResult(devId,
-                msg->data.enroll.finger.fid,
-                msg->data.enroll.finger.gid,
-                msg->data.enroll.samples_remaining);
+            if (!thisPtr->mClientCallback->onEnrollResult(devId,
+                    msg->data.enroll.finger.fid,
+                    msg->data.enroll.finger.gid,
+                    msg->data.enroll.samples_remaining).isOk()) {
+                ALOGE("failed to invoke fingerprint onEnrollResult callback");
+            }
             break;
         case FINGERPRINT_TEMPLATE_REMOVED:
-            thisPtr->mClientCallback->onRemoved(devId,
-                msg->data.removed.finger.fid,
-                msg->data.removed.finger.gid,
-                msg->data.removed.remaining_templates);
+            if (!thisPtr->mClientCallback->onRemoved(devId,
+                    msg->data.removed.finger.fid,
+                    msg->data.removed.finger.gid,
+                    msg->data.removed.remaining_templates).isOk()) {
+                ALOGE("failed to invoke fingerprint onRemoved callback");
+            }
             break;
         case FINGERPRINT_AUTHENTICATED:
             if (msg->data.authenticated.finger.fid != 0) {
@@ -292,23 +300,29 @@
                     reinterpret_cast<const uint8_t *>(&msg->data.authenticated.hat);
                 const hidl_vec<uint8_t> token(
                     std::vector<uint8_t>(hat, hat + sizeof(msg->data.authenticated.hat)));
-                thisPtr->mClientCallback->onAuthenticated(devId,
-                    msg->data.authenticated.finger.fid,
-                    msg->data.authenticated.finger.gid,
-                    token);
+                if (!thisPtr->mClientCallback->onAuthenticated(devId,
+                        msg->data.authenticated.finger.fid,
+                        msg->data.authenticated.finger.gid,
+                        token).isOk()) {
+                    ALOGE("failed to invoke fingerprint onAuthenticated callback");
+                }
             } else {
                 // Not a recognized fingerprint
-                thisPtr->mClientCallback->onAuthenticated(devId,
-                    msg->data.authenticated.finger.fid,
-                    msg->data.authenticated.finger.gid,
-                    hidl_vec<uint8_t>());
+                if (!thisPtr->mClientCallback->onAuthenticated(devId,
+                        msg->data.authenticated.finger.fid,
+                        msg->data.authenticated.finger.gid,
+                        hidl_vec<uint8_t>()).isOk()) {
+                    ALOGE("failed to invoke fingerprint onAuthenticated callback");
+                }
             }
             break;
         case FINGERPRINT_TEMPLATE_ENUMERATING:
-            thisPtr->mClientCallback->onEnumerate(devId,
-                msg->data.enumerated.finger.fid,
-                msg->data.enumerated.finger.gid,
-                msg->data.enumerated.remaining_templates);
+            if (!thisPtr->mClientCallback->onEnumerate(devId,
+                    msg->data.enumerated.finger.fid,
+                    msg->data.enumerated.finger.gid,
+                    msg->data.enumerated.remaining_templates).isOk()) {
+                ALOGE("failed to invoke fingerprint onEnumerate callback");
+            }
             break;
     }
 }
diff --git a/gnss/1.0/default/Gnss.cpp b/gnss/1.0/default/Gnss.cpp
index 9493737..afb659c 100644
--- a/gnss/1.0/default/Gnss.cpp
+++ b/gnss/1.0/default/Gnss.cpp
@@ -46,7 +46,11 @@
     .gnss_sv_status_cb = gnssSvStatusCb,
 };
 
-Gnss::Gnss(gps_device_t* gnssDevice) {
+uint32_t Gnss::sCapabilitiesCached = 0;
+uint16_t Gnss::sYearOfHwCached = 0;
+
+Gnss::Gnss(gps_device_t* gnssDevice) :
+        mDeathRecipient(new GnssHidlDeathRecipient(this)) {
     /* Error out if an instance of the interface already exists. */
     LOG_ALWAYS_FATAL_IF(sInterfaceExists);
     sInterfaceExists = true;
@@ -271,6 +275,9 @@
     if (!ret.isOk()) {
         ALOGE("%s: Unable to invoke callback", __func__);
     }
+
+    // Save for reconnection when some legacy hal's don't resend this info
+    sCapabilitiesCached = capabilities;
 }
 
 void Gnss::acquireWakelockCb() {
@@ -373,6 +380,9 @@
     if (!ret.isOk()) {
             ALOGE("%s: Unable to invoke callback", __func__);
     }
+
+    // Save for reconnection when some legacy hal's don't resend this info
+    sYearOfHwCached = info->year_of_hw;
 }
 
 
@@ -383,7 +393,30 @@
         return false;
     }
 
+    if (callback == nullptr)  {
+        ALOGE("%s: Null callback ignored", __func__);
+        return false;
+    }
+
+    if (sGnssCbIface != NULL) {
+        ALOGW("%s called more than once. Unexpected unless test.", __func__);
+        sGnssCbIface->unlinkToDeath(mDeathRecipient);
+    }
+
     sGnssCbIface = callback;
+    callback->linkToDeath(mDeathRecipient, 0 /*cookie*/);
+
+    // If this was received in the past, send it up again to refresh caller.
+    // mGnssIface will override after init() is called below, if needed
+    // (though it's unlikely the gps.h capabilities or system info will change.)
+    if (sCapabilitiesCached != 0) {
+        setCapabilitiesCb(sCapabilitiesCached);
+    }
+    if (sYearOfHwCached != 0) {
+        LegacyGnssSystemInfo info;
+        info.year_of_hw = sYearOfHwCached;
+        setSystemInfoCb(&info);
+    }
 
     return (mGnssIface->init(&sGnssCb) == 0);
 }
@@ -676,6 +709,30 @@
     return mGnssBatching;
 }
 
+void Gnss::handleHidlDeath() {
+    ALOGW("GNSS service noticed HIDL death. Stopping all GNSS operations.");
+
+    // commands down to the HAL implementation
+    stop(); // stop ongoing GPS tracking
+    if (mGnssMeasurement != nullptr) {
+        mGnssMeasurement->close();
+    }
+    if (mGnssNavigationMessage != nullptr) {
+        mGnssNavigationMessage->close();
+    }
+    if (mGnssBatching != nullptr) {
+        mGnssBatching->stop();
+        mGnssBatching->cleanup();
+    }
+    cleanup();
+
+    /*
+     * This has died, so close it off in case (race condition) callbacks happen
+     * before HAL processes above messages.
+     */
+    sGnssCbIface = nullptr;
+}
+
 IGnss* HIDL_FETCH_IGnss(const char* /* hal */) {
     hw_module_t* module;
     IGnss* iface = nullptr;
diff --git a/gnss/1.0/default/Gnss.h b/gnss/1.0/default/Gnss.h
index 63614fa..faf903c 100644
--- a/gnss/1.0/default/Gnss.h
+++ b/gnss/1.0/default/Gnss.h
@@ -52,7 +52,8 @@
  * Represents the standard GNSS interface. Also contains wrapper methods to allow methods from
  * IGnssCallback interface to be passed into the conventional implementation of the GNSS HAL.
  */
-struct Gnss : public IGnss {
+class Gnss : public IGnss {
+  public:
     Gnss(gps_device_t* gnss_device);
     ~Gnss();
 
@@ -122,6 +123,22 @@
     static GpsCallbacks sGnssCb;
 
  private:
+    /*
+     * For handling system-server death while GNSS service lives on.
+     */
+    class GnssHidlDeathRecipient : public hidl_death_recipient {
+      public:
+        GnssHidlDeathRecipient(const sp<Gnss> gnss) : mGnss(gnss) {
+        }
+
+        virtual void serviceDied(uint64_t /*cookie*/,
+                const wp<::android::hidl::base::V1_0::IBase>& /*who*/) {
+            mGnss->handleHidlDeath();
+        }
+      private:
+        sp<Gnss> mGnss;
+    };
+
     // for wakelock consolidation, see above
     static void acquireWakelockGnss();
     static void releaseWakelockGnss();
@@ -129,6 +146,11 @@
     static bool sWakelockHeldGnss;
     static bool sWakelockHeldFused;
 
+    /*
+     * Cleanup for death notification
+     */
+    void handleHidlDeath();
+
     sp<GnssXtra> mGnssXtraIface = nullptr;
     sp<AGnssRil> mGnssRil = nullptr;
     sp<GnssGeofencing> mGnssGeofencingIface = nullptr;
@@ -139,10 +161,17 @@
     sp<GnssDebug> mGnssDebug = nullptr;
     sp<GnssConfiguration> mGnssConfig = nullptr;
     sp<GnssBatching> mGnssBatching = nullptr;
+
+    sp<GnssHidlDeathRecipient> mDeathRecipient;
+
     const GpsInterface* mGnssIface = nullptr;
     static sp<IGnssCallback> sGnssCbIface;
     static std::vector<std::unique_ptr<ThreadFuncArgs>> sThreadFuncArgsList;
     static bool sInterfaceExists;
+
+    // Values saved for resend
+    static uint32_t sCapabilitiesCached;
+    static uint16_t sYearOfHwCached;
 };
 
 extern "C" IGnss* HIDL_FETCH_IGnss(const char* name);
diff --git a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
index 8f131cf..21b7136 100644
--- a/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
+++ b/gnss/1.0/vts/functional/VtsHalGnssV1_0TargetTest.cpp
@@ -33,17 +33,16 @@
 using android::hardware::gnss::V1_0::IGnssCallback;
 using android::sp;
 
-#define TIMEOUT_SECONDS 5  // for basic commands/responses
+#define TIMEOUT_SEC 3  // for basic commands/responses
 
 // The main test class for GNSS HAL.
 class GnssHalTest : public ::testing::VtsHalHidlTargetTestBase {
  public:
   virtual void SetUp() override {
-    /* TODO(b/35678469): Setup the init.rc for VTS such that there's a
-     * single caller
-     * to the GNSS HAL - as part of confirming that the info & capabilities
-     * callbacks trigger.
-     */
+    // Clean between tests
+    capabilities_called_count_ = 0;
+    location_called_count_ = 0;
+    info_called_count_ = 0;
 
     gnss_hal_ = ::testing::VtsHalHidlTargetTestBase::getService<IGnss>();
     ASSERT_NE(gnss_hal_, nullptr);
@@ -53,15 +52,35 @@
 
     auto result = gnss_hal_->setCallback(gnss_cb_);
     if (!result.isOk()) {
-      ALOGE("result of failed callback set %s", result.description().c_str());
+      ALOGE("result of failed setCallback %s", result.description().c_str());
     }
 
     ASSERT_TRUE(result.isOk());
     ASSERT_TRUE(result);
 
-    /* TODO(b/35678469): Implement the capabilities & info (year) checks &
-     * value store here.
+    /*
+     * At least one callback should trigger - it may be capabilites, or
+     * system info first, so wait again if capabilities not received.
      */
+    EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
+    if (capabilities_called_count_ == 0) {
+      EXPECT_EQ(std::cv_status::no_timeout, wait(TIMEOUT_SEC));
+    }
+
+    /*
+     * Generally should be 1 capabilites callback -
+     * or possibly 2 in some recovery cases (default cached & refreshed)
+     */
+    EXPECT_GE(capabilities_called_count_, 1);
+    EXPECT_LE(capabilities_called_count_, 2);
+
+    /*
+     * Clear notify/waiting counter, allowing up till the timeout after
+     * the last reply for final startup messages to arrive (esp. system
+     * info.)
+     */
+    while (wait(TIMEOUT_SEC) == std::cv_status::no_timeout) {
+    }
   }
 
   virtual void TearDown() override {
@@ -93,9 +112,9 @@
 
   /* Callback class for data & Event. */
   class GnssCallback : public IGnssCallback {
+   public:
     GnssHalTest& parent_;
 
-   public:
     GnssCallback(GnssHalTest& parent) : parent_(parent){};
 
     virtual ~GnssCallback() = default;
@@ -171,16 +190,33 @@
  * Sets up the callback, awaits the capabilities, and calls cleanup
  *
  * Since this is just the basic operation of SetUp() and TearDown(),
- * the function definition is intentionally kept empty
+ * the function definition is intentionally empty
  */
 TEST_F(GnssHalTest, SetCallbackCapabilitiesCleanup) {}
 
-void CheckLocation(GnssLocation& location) {
+/*
+ * CheckLocation:
+ * Helper function to vet Location fields
+ */
+
+void CheckLocation(GnssLocation& location, bool checkAccuracies) {
   EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
   EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
   EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_SPEED);
   EXPECT_TRUE(location.gnssLocationFlags &
               GnssLocationFlags::HAS_HORIZONTAL_ACCURACY);
+  // New uncertainties available in O must be provided,
+  // at least when paired with modern hardware (2017+)
+  if (checkAccuracies) {
+    EXPECT_TRUE(location.gnssLocationFlags &
+                GnssLocationFlags::HAS_VERTICAL_ACCURACY);
+    EXPECT_TRUE(location.gnssLocationFlags &
+                GnssLocationFlags::HAS_SPEED_ACCURACY);
+    if (location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING) {
+      EXPECT_TRUE(location.gnssLocationFlags &
+                  GnssLocationFlags::HAS_BEARING_ACCURACY);
+    }
+  }
   EXPECT_GE(location.latitudeDegrees, -90.0);
   EXPECT_LE(location.latitudeDegrees, 90.0);
   EXPECT_GE(location.longitudeDegrees, -180.0);
@@ -190,12 +226,17 @@
   EXPECT_GE(location.speedMetersPerSec, 0.0);
   EXPECT_LE(location.speedMetersPerSec, 5.0);  // VTS tests are stationary.
 
+  // Non-zero speeds must be reported with an associated bearing
+  if (location.speedMetersPerSec > 0.0) {
+    EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_BEARING);
+  }
+
   /*
    * Tolerating some especially high values for accuracy estimate, in case of
-   * first fix with especially poor geoemtry (happens occasionally)
+   * first fix with especially poor geometry (happens occasionally)
    */
   EXPECT_GT(location.horizontalAccuracyMeters, 0.0);
-  EXPECT_LE(location.horizontalAccuracyMeters, 200.0);
+  EXPECT_LE(location.horizontalAccuracyMeters, 250.0);
 
   /*
    * Some devices may define bearing as -180 to +180, others as 0 to 360.
@@ -220,11 +261,6 @@
 
   // Check timestamp > 1.48e12 (47 years in msec - 1970->2017+)
   EXPECT_GT(location.timestamp, 1.48e12);
-
-  /* TODO(b/35678469): Check if the hardware year is 2017+, and if so,
-   * that bearing, plus vertical, speed & bearing accuracy are present.
-   * And allow bearing to be not present, only if associated with a speed of 0.0
-   */
 }
 
 /*
@@ -241,6 +277,9 @@
 #define LOCATION_TIMEOUT_SUBSEQUENT_SEC 3
 #define LOCATIONS_TO_CHECK 5
 
+  bool checkMoreAccuracies =
+      (info_called_count_ > 0 && last_info_.yearOfHw >= 2017);
+
   auto result = gnss_hal_->setPositionMode(
       IGnss::GnssPositionMode::MS_BASED,
       IGnss::GnssPositionRecurrence::RECURRENCE_PERIODIC, MIN_INTERVAL_MSEC,
@@ -254,15 +293,18 @@
   ASSERT_TRUE(result.isOk());
   ASSERT_TRUE(result);
 
-  EXPECT_EQ(std::cv_status::no_timeout, wait(LOCATION_TIMEOUT_FIRST_SEC));
-  EXPECT_EQ(location_called_count_, 1);
-  CheckLocation(last_location_);
+  // GPS signals initially optional for this test, so don't expect no timeout
+  // yet
+  wait(LOCATION_TIMEOUT_FIRST_SEC);
+  if (location_called_count_ > 0) {
+    CheckLocation(last_location_, checkMoreAccuracies);
+  }
 
   for (int i = 1; i < LOCATIONS_TO_CHECK; i++) {
-    EXPECT_EQ(std::cv_status::no_timeout,
-              wait(LOCATION_TIMEOUT_SUBSEQUENT_SEC));
-    EXPECT_EQ(location_called_count_, i + 1);
-    CheckLocation(last_location_);
+    wait(LOCATION_TIMEOUT_SUBSEQUENT_SEC);
+    if (location_called_count_ > 0) {
+      CheckLocation(last_location_, checkMoreAccuracies);
+    }
   }
 
   result = gnss_hal_->stop();
@@ -276,4 +318,4 @@
   int status = RUN_ALL_TESTS();
   ALOGI("Test result = %d", status);
   return status;
-}
+}
\ No newline at end of file
diff --git a/graphics/composer/2.1/default/ComposerClient.cpp b/graphics/composer/2.1/default/ComposerClient.cpp
index a2d5d4b..d599b44 100644
--- a/graphics/composer/2.1/default/ComposerClient.cpp
+++ b/graphics/composer/2.1/default/ComposerClient.cpp
@@ -21,7 +21,7 @@
 #include <log/log.h>
 
 #include "ComposerClient.h"
-#include "Hwc.h"
+#include "ComposerBase.h"
 #include "IComposerCommandBuffer.h"
 
 namespace android {
diff --git a/graphics/composer/2.1/default/ComposerClient.h b/graphics/composer/2.1/default/ComposerClient.h
index 14da1f8..c973351 100644
--- a/graphics/composer/2.1/default/ComposerClient.h
+++ b/graphics/composer/2.1/default/ComposerClient.h
@@ -21,8 +21,9 @@
 #include <unordered_map>
 #include <vector>
 
-#include "Hwc.h"
+#include <hardware/hwcomposer2.h>
 #include "IComposerCommandBuffer.h"
+#include "ComposerBase.h"
 
 namespace android {
 namespace hardware {
diff --git a/graphics/composer/2.1/default/Hwc.cpp b/graphics/composer/2.1/default/Hwc.cpp
index e6ff9e0..1497065 100644
--- a/graphics/composer/2.1/default/Hwc.cpp
+++ b/graphics/composer/2.1/default/Hwc.cpp
@@ -16,12 +16,12 @@
 
 #define LOG_TAG "HwcPassthrough"
 
-#include <type_traits>
+#include "Hwc.h"
 
+#include <type_traits>
 #include <log/log.h>
 
 #include "ComposerClient.h"
-#include "Hwc.h"
 #include "hardware/hwcomposer.h"
 #include "hwc2on1adapter/HWC2On1Adapter.h"
 
diff --git a/sensors/1.0/default/Sensors.cpp b/sensors/1.0/default/Sensors.cpp
index 2457310..1100dd6 100644
--- a/sensors/1.0/default/Sensors.cpp
+++ b/sensors/1.0/default/Sensors.cpp
@@ -97,6 +97,15 @@
     // is considered optional.
     CHECK_GE(getHalDeviceVersion(), SENSORS_DEVICE_API_VERSION_1_3);
 
+    if (getHalDeviceVersion() == SENSORS_DEVICE_API_VERSION_1_4) {
+        if (mSensorDevice->inject_sensor_data == nullptr) {
+            LOG(ERROR) << "HAL specifies version 1.4, but does not implement inject_sensor_data()";
+        }
+        if (mSensorModule->set_operation_mode == nullptr) {
+            LOG(ERROR) << "HAL specifies version 1.4, but does not implement set_operation_mode()";
+        }
+    }
+
     mInitCheck = OK;
 }
 
@@ -132,6 +141,10 @@
 }
 
 Return<Result> Sensors::setOperationMode(OperationMode mode) {
+    if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4
+            || mSensorModule->set_operation_mode == nullptr) {
+        return Result::INVALID_OPERATION;
+    }
     return ResultFromStatus(mSensorModule->set_operation_mode((uint32_t)mode));
 }
 
@@ -236,7 +249,8 @@
 }
 
 Return<Result> Sensors::injectSensorData(const Event& event) {
-    if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4) {
+    if (getHalDeviceVersion() < SENSORS_DEVICE_API_VERSION_1_4
+            || mSensorDevice->inject_sensor_data == nullptr) {
         return Result::INVALID_OPERATION;
     }
 
diff --git a/update-makefiles.sh b/update-makefiles.sh
index d0cb91c..88cc97b 100755
--- a/update-makefiles.sh
+++ b/update-makefiles.sh
@@ -1,52 +1,8 @@
 #!/bin/bash
 
-if [ ! -d hardware/interfaces ] ; then
-  echo "Where is hardware/interfaces?";
-  exit 1;
-fi
+source system/tools/hidl/update-makefiles-helper.sh
 
-if [ ! -d system/libhidl/transport ] ; then
-  echo "Where is system/libhidl/transport?";
-  exit 1;
-fi
+do_makefiles_update \
+  "android.hardware:hardware/interfaces" \
+  "android.hidl:system/libhidl/transport"
 
-packages=$(pushd hardware/interfaces > /dev/null; \
-           find . -type f -name \*.hal -exec dirname {} \; | sort -u | \
-           cut -c3- | \
-           awk -F'/' \
-                '{printf("android.hardware"); for(i=1;i<NF;i++){printf(".%s", $i);}; printf("@%s\n", $NF);}'; \
-           popd > /dev/null)
-
-for p in $packages; do
-  echo "Updating $p";
-  hidl-gen -Lmakefile -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport $p;
-  rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
-  hidl-gen -Landroidbp -r android.hardware:hardware/interfaces -r android.hidl:system/libhidl/transport $p;
-  rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
-done
-
-# subdirectories of hardware/interfaces which contain an Android.bp file
-android_dirs=$(find hardware/interfaces/*/     \
-              -name "Android.bp"               \
-              -printf "%h\n"                   \
-              | cut -d "/" -f1-3               \
-              | sort | uniq)
-
-echo "Updating Android.bp files."
-
-for bp_dir in $android_dirs; do
-  bp="$bp_dir/Android.bp"
-  # locations of Android.bp files in specific subdirectory of hardware/interfaces
-  android_bps=$(find $bp_dir                   \
-                -name "Android.bp"             \
-                ! -path $bp_dir/Android.bp     \
-                -printf "%h\n"                 \
-                | sort)
-
-  echo "// This is an autogenerated file, do not edit." > "$bp";
-  echo "subdirs = [" >> "$bp";
-  for a in $android_bps; do
-    echo "    \"${a#$bp_dir/}\"," >> "$bp";
-  done
-  echo "]" >> "$bp";
-done
diff --git a/vibrator/1.0/Android.mk b/vibrator/1.0/Android.mk
index 4e1ba6a..d921a7e 100644
--- a/vibrator/1.0/Android.mk
+++ b/vibrator/1.0/Android.mk
@@ -17,6 +17,25 @@
 
 
 #
+# Build types.hal (Effect)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Effect.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.vibrator@1.0::types.Effect
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (Status)
 #
 GEN := $(intermediates)/android/hardware/vibrator/V1_0/Status.java
@@ -73,6 +92,25 @@
 
 
 #
+# Build types.hal (Effect)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Effect.java
+$(GEN): $(HIDL)
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_DEPS := $(LOCAL_PATH)/types.hal
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.vibrator@1.0::types.Effect
+
+$(GEN): $(LOCAL_PATH)/types.hal
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+
+#
 # Build types.hal (Status)
 #
 GEN := $(intermediates)/android/hardware/vibrator/V1_0/Status.java
@@ -114,5 +152,39 @@
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
 
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := android.hardware.vibrator@1.0-java-constants
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+
+intermediates := $(local-generated-sources-dir)
+
+HIDL := $(HOST_OUT_EXECUTABLES)/hidl-gen$(HOST_EXECUTABLE_SUFFIX)
+#
+GEN := $(intermediates)/android/hardware/vibrator/V1_0/Constants.java
+$(GEN): $(HIDL)
+$(GEN): $(LOCAL_PATH)/types.hal
+$(GEN): $(LOCAL_PATH)/IVibrator.hal
+
+$(GEN): PRIVATE_HIDL := $(HIDL)
+$(GEN): PRIVATE_OUTPUT_DIR := $(intermediates)
+$(GEN): PRIVATE_CUSTOM_TOOL = \
+        $(PRIVATE_HIDL) -o $(PRIVATE_OUTPUT_DIR) \
+        -Ljava-constants \
+        -randroid.hardware:hardware/interfaces \
+        -randroid.hidl:system/libhidl/transport \
+        android.hardware.vibrator@1.0
+
+$(GEN):
+	$(transform-generated-source)
+LOCAL_GENERATED_SOURCES += $(GEN)
+# Avoid dependency cycle of framework.jar -> this-library -> framework.jar
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_JAVA_LIBRARIES := core-oj
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+
 
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/vibrator/1.0/IVibrator.hal b/vibrator/1.0/IVibrator.hal
index 0a4ffca..757ad0d 100644
--- a/vibrator/1.0/IVibrator.hal
+++ b/vibrator/1.0/IVibrator.hal
@@ -17,7 +17,8 @@
 package android.hardware.vibrator@1.0;
 
 interface IVibrator {
-  /** Turn on vibrator
+  /**
+   * Turn on vibrator
    *
    * This function must only be called after the previous timeout has expired or
    * was canceled (through off()).
@@ -26,10 +27,46 @@
    */
   on(uint32_t timeoutMs) generates (Status vibratorOnRet);
 
-  /** Turn off vibrator
+  /**
+   * Turn off vibrator
    *
    * Cancel a previously-started vibration, if any.
    * @return vibratorOffRet whether vibrator command was successful or not.
    */
   off() generates (Status vibratorOffRet);
+
+  /**
+   * Returns whether the vibrator supports changes to its vibrational amplitude.
+   */
+  supportsAmplitudeControl() generates (bool supports);
+
+  /**
+   * Sets the motor's vibrational amplitude.
+   *
+   * Changes the force being produced by the underlying motor.
+   *
+   * @param amplitude The unitless force setting. Note that this number must
+   *                  be between 1 and 255, inclusive. If the motor does not
+   *                  have exactly 255 steps, it must do it's best to map it
+   *                  onto the number of steps it does have.
+   * @return status Whether the command was successful or not. Must return
+   *                Status::UNSUPPORTED_OPERATION if setting the amplitude is
+   *                not supported by the device.
+   */
+  setAmplitude(uint8_t amplitude) generates (Status status);
+
+  /**
+   * Fire off a predefined haptic event.
+   *
+   * @param event The type of haptic event to trigger.
+   * @return status Whether the effect was successfully performed or not. Must
+   *                return Status::UNSUPPORTED_OPERATION is the effect is not
+   *                supported.
+   * @return lengthMs The length of time the event is expected to take in
+   *                  milliseconds. This doesn't need to be perfectly accurate,
+   *                  but should be a reasonable approximation. Should be a
+   *                  positive, non-zero value if the returned status is
+   *                  Status::OK, and set to 0 otherwise.
+   */
+  perform(Effect effect, EffectStrength strength) generates (Status status, uint32_t lengthMs);
 };
diff --git a/vibrator/1.0/default/Vibrator.cpp b/vibrator/1.0/default/Vibrator.cpp
index 8c82bcd..19cf3dc 100644
--- a/vibrator/1.0/default/Vibrator.cpp
+++ b/vibrator/1.0/default/Vibrator.cpp
@@ -16,6 +16,8 @@
 
 #define LOG_TAG "VibratorService"
 
+#include <inttypes.h>
+
 #include <log/log.h>
 
 #include <hardware/hardware.h>
@@ -36,7 +38,7 @@
     int32_t ret = mDevice->vibrator_on(mDevice, timeout_ms);
     if (ret != 0) {
         ALOGE("on command failed : %s", strerror(-ret));
-        return Status::ERR;
+        return Status::UNKNOWN_ERROR;
     }
     return Status::OK;
 }
@@ -45,11 +47,24 @@
     int32_t ret = mDevice->vibrator_off(mDevice);
     if (ret != 0) {
         ALOGE("off command failed : %s", strerror(-ret));
-        return Status::ERR;
+        return Status::UNKNOWN_ERROR;
     }
     return Status::OK;
 }
 
+Return<bool> Vibrator::supportsAmplitudeControl()  {
+    return false;
+}
+
+Return<Status> Vibrator::setAmplitude(uint8_t) {
+    return Status::UNSUPPORTED_OPERATION;
+}
+
+Return<void> Vibrator::perform(Effect, EffectStrength, perform_cb _hidl_cb) {
+    _hidl_cb(Status::UNSUPPORTED_OPERATION, 0);
+    return Void();
+}
+
 IVibrator* HIDL_FETCH_IVibrator(const char * /*hal*/) {
     vibrator_device_t *vib_device;
     const hw_module_t *hw_module = nullptr;
diff --git a/vibrator/1.0/default/Vibrator.h b/vibrator/1.0/default/Vibrator.h
index 061b364..bea6ea8 100644
--- a/vibrator/1.0/default/Vibrator.h
+++ b/vibrator/1.0/default/Vibrator.h
@@ -26,23 +26,18 @@
 namespace V1_0 {
 namespace implementation {
 
-using ::android::hardware::vibrator::V1_0::IVibrator;
-using ::android::hardware::vibrator::V1_0::Status;
-using ::android::hardware::Return;
-using ::android::hardware::Void;
-using ::android::hardware::hidl_vec;
-using ::android::hardware::hidl_string;
-using ::android::sp;
-
 struct Vibrator : public IVibrator {
   Vibrator(vibrator_device_t *device);
 
   // Methods from ::android::hardware::vibrator::V1_0::IVibrator follow.
   Return<Status> on(uint32_t timeoutMs)  override;
   Return<Status> off()  override;
+  Return<bool> supportsAmplitudeControl() override;
+  Return<Status> setAmplitude(uint8_t amplitude) override;
+  Return<void> perform(Effect effect, EffectStrength strength, perform_cb _hidl_cb) override;
 
-  private:
-    vibrator_device_t    *mDevice;
+private:
+  vibrator_device_t    *mDevice;
 };
 
 extern "C" IVibrator* HIDL_FETCH_IVibrator(const char* name);
diff --git a/vibrator/1.0/types.hal b/vibrator/1.0/types.hal
index 8fc5683..a080c07 100644
--- a/vibrator/1.0/types.hal
+++ b/vibrator/1.0/types.hal
@@ -16,7 +16,33 @@
 
 package android.hardware.vibrator@1.0;
 
-enum Status: uint32_t {
-    OK             = 0,
-    ERR            = 1
+enum Status : uint32_t {
+    OK,
+    UNKNOWN_ERROR,
+    BAD_VALUE,
+    UNSUPPORTED_OPERATION
+};
+
+@export
+enum Effect : uint32_t {
+    /**
+     * A single click effect.
+     *
+     * This effect should produce a sharp, crisp click sensation.
+     */
+    CLICK,
+    /**
+     * A double click effect.
+     *
+     * This effect should produce two sequential sharp, crisp click sensations with a minimal
+     * amount of time between them.
+     */
+    DOUBLE_CLICK
+};
+
+@export
+enum EffectStrength : uint8_t {
+    LIGHT,
+    MEDIUM,
+    STRONG
 };
diff --git a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
index a978f2c..f415ad5 100644
--- a/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
+++ b/vibrator/1.0/vts/functional/VtsHalVibratorV1_0TargetTest.cpp
@@ -22,6 +22,8 @@
 #include <VtsHalHidlTargetTestBase.h>
 #include <unistd.h>
 
+using ::android::hardware::vibrator::V1_0::Effect;
+using ::android::hardware::vibrator::V1_0::EffectStrength;
 using ::android::hardware::vibrator::V1_0::IVibrator;
 using ::android::hardware::vibrator::V1_0::Status;
 using ::android::hardware::Return;
@@ -50,12 +52,49 @@
  private:
 };
 
+static void validatePerformEffect(Status status, uint32_t lengthMs) {
+  ASSERT_TRUE(status == Status::OK || status == Status::UNSUPPORTED_OPERATION);
+  if (status == Status::OK) {
+      ASSERT_GT(lengthMs, static_cast<uint32_t>(0));
+  } else {
+      ASSERT_EQ(lengthMs, static_cast<uint32_t>(0));
+  }
+}
+
 TEST_F(VibratorHidlTest, OnThenOffBeforeTimeout) {
   EXPECT_EQ(Status::OK, vibrator->on(2000));
   sleep(1);
   EXPECT_EQ(Status::OK, vibrator->off());
 }
 
+TEST_F(VibratorHidlTest, PerformEffect) {
+  vibrator->perform(Effect::CLICK, EffectStrength::MEDIUM, validatePerformEffect);
+  vibrator->perform(Effect::DOUBLE_CLICK, EffectStrength::LIGHT, validatePerformEffect);
+}
+
+TEST_F(VibratorHidlTest, ChangeVibrationalAmplitude) {
+  if (vibrator->supportsAmplitudeControl()) {
+    EXPECT_EQ(Status::OK, vibrator->setAmplitude(1));
+    EXPECT_EQ(Status::OK, vibrator->on(2000));
+    EXPECT_EQ(Status::OK, vibrator->setAmplitude(128));
+    sleep(1);
+    EXPECT_EQ(Status::OK, vibrator->setAmplitude(255));
+    sleep(1);
+  }
+}
+
+TEST_F(VibratorHidlTest, AmplitudeOutsideRangeFails) {
+  if (vibrator->supportsAmplitudeControl()) {
+    EXPECT_EQ(Status::BAD_VALUE, vibrator->setAmplitude(0));
+  }
+}
+
+TEST_F(VibratorHidlTest, SetAmplitudeReturnUnsupportedOperationIfNotSupported) {
+  if (!vibrator->supportsAmplitudeControl()) {
+    EXPECT_EQ(Status::UNSUPPORTED_OPERATION, vibrator->setAmplitude(1));
+  }
+}
+
 int main(int argc, char **argv) {
   ::testing::AddGlobalTestEnvironment(new VibratorHidlEnvironment);
   ::testing::InitGoogleTest(&argc, argv);
diff --git a/wifi/1.0/default/wifi_legacy_hal.cpp b/wifi/1.0/default/wifi_legacy_hal.cpp
index 5fc0228..ba57ba7 100644
--- a/wifi/1.0/default/wifi_legacy_hal.cpp
+++ b/wifi/1.0/default/wifi_legacy_hal.cpp
@@ -328,9 +328,8 @@
   wifi_error status = init_wifi_vendor_hal_func_table(&global_func_table_);
   if (status != WIFI_SUCCESS) {
     LOG(ERROR) << "Failed to initialize legacy hal function table";
-    return WIFI_ERROR_UNKNOWN;
   }
-  return WIFI_SUCCESS;
+  return status;
 }
 
 wifi_error WifiLegacyHal::start() {
diff --git a/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal b/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
index 166ad96..173cce9 100644
--- a/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
+++ b/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.hal
@@ -346,6 +346,24 @@
   };
 
   /**
+   * BSSID change Reasons.
+   */
+  enum BssidChangeReason : uint8_t {
+    /**
+     * Started association with new bssid.
+     */
+    ASSOC_START = 0,
+    /**
+     * Completed association with new bssid.
+     */
+    ASSOC_COMPLETE = 1,
+    /**
+     * Dis-association with current bssid.
+     */
+    DISASSOC = 2
+  };
+
+  /**
    * Used to indicate that a new network has been added.
    *
    * @param id Network ID allocated to the corresponding network.
@@ -466,6 +484,16 @@
   oneway onEapFailure();
 
   /**
+   * Used to indicate the change of active bssid.
+   * This is useful to figure out when the driver/firmware roams to a bssid
+   * on its own.
+   *
+   * @param reason Reason why the bssid changed.
+   * @param bssid BSSID of the corresponding AP.
+   */
+  oneway onBssidChanged(BssidChangeReason reason, Bssid bssid);
+
+  /**
    * Used to indicate the success of a WPS connection attempt.
    */
   oneway onWpsEventSuccess();