Merge "Add new values to KeyRequestType"
diff --git a/automotive/vehicle/2.0/Android.bp b/automotive/vehicle/2.0/Android.bp
index ffe012e..a13359e 100644
--- a/automotive/vehicle/2.0/Android.bp
+++ b/automotive/vehicle/2.0/Android.bp
@@ -66,6 +66,7 @@
         "VmsMessageWithLayerAndPublisherIdIntegerValuesIndex",
         "VmsMessageWithLayerIntegerValuesIndex",
         "VmsOfferingMessageIntegerValuesIndex",
+        "VmsPublisherInformationIntegerValuesIndex",
         "VmsSubscriptionsStateIntegerValuesIndex",
         "Wheel",
     ],
diff --git a/automotive/vehicle/2.0/types.hal b/automotive/vehicle/2.0/types.hal
index 7e42781..d88479a 100644
--- a/automotive/vehicle/2.0/types.hal
+++ b/automotive/vehicle/2.0/types.hal
@@ -2894,9 +2894,42 @@
      * A message from the VMS service to the subscribers or from the publishers to the VMS service
      * with a serialized VMS data packet as defined in the VMS protocol.
      *
-     * This message type uses enum VmsBaseMessageIntegerValuesIndex.
+     * This message type uses enum VmsMessageWithLayerAndPublisherIdIntegerValuesIndex.
      */
     DATA = 12,
+
+    /**
+     * A request from the publishers to the VMS service to get a Publisher ID for a serialized VMS
+     * provider description packet as defined in the VMS protocol.
+     *
+     * This message type uses enum VmsBaseMessageIntegerValuesIndex.
+     */
+    PUBLISHER_ID_REQUEST = 13,
+
+    /**
+     * A response from the VMS service to the publisher that contains a provider description packet
+     * and the publisher ID assigned to it.
+     *
+     * This message type uses enum VmsPublisherInformationIntegerValuesIndex.
+     */
+    PUBLISHER_ID_RESPONSE = 14,
+
+    /**
+     * A request from the subscribers to the VMS service to get information for a Publisher ID.
+     *
+     * This message type uses enum VmsPublisherInformationIntegerValuesIndex.
+     */
+    PUBLISHER_INFORMATION_REQUEST = 15,
+
+    /**
+     * A response from the VMS service to the subscribers that contains a provider description packet
+     * and the publisher ID assigned to it.
+     *
+     * This message type uses enum VmsPublisherInformationIntegerValuesIndex.
+     */
+    PUBLISHER_INFORMATION_RESPONSE = 16,
+
+    LAST_VMS_MESSAGE_TYPE = PUBLISHER_INFORMATION_RESPONSE,
 };
 
 /**
@@ -2924,7 +2957,8 @@
 
 /*
  * A VMS message with a layer and publisher ID is sent as part of a
- * VmsMessageType.SUBSCRIBE_TO_PUBLISHER and VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER messages.
+ * VmsMessageType.SUBSCRIBE_TO_PUBLISHER, VmsMessageType.UNSUBSCRIBE_TO_PUBLISHER messages and
+ * VmsMessageType.DATA .
  */
 enum VmsMessageWithLayerAndPublisherIdIntegerValuesIndex : VmsMessageWithLayerIntegerValuesIndex {
     PUBLISHER_ID = 4,
@@ -2993,3 +3027,11 @@
     LAYERS_START = 3,
 };
 
+/*
+ * Publishers send the VMS service their information and assigned in response a publisher ID.
+ * Subscribers can request the publisher information for a publisher ID they received in other messages.
+ */
+enum VmsPublisherInformationIntegerValuesIndex : VmsBaseMessageIntegerValuesIndex {
+    PUBLISHER_ID = 1,
+};
+
diff --git a/camera/device/3.2/default/CameraDeviceSession.cpp b/camera/device/3.2/default/CameraDeviceSession.cpp
index 31b4739..ae275ae 100644
--- a/camera/device/3.2/default/CameraDeviceSession.cpp
+++ b/camera/device/3.2/default/CameraDeviceSession.cpp
@@ -738,8 +738,14 @@
 // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow.
 Return<void> CameraDeviceSession::constructDefaultRequestSettings(
         RequestTemplate type, ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)  {
-    Status status = initStatus();
     CameraMetadata outMetadata;
+    Status status = constructDefaultRequestSettingsRaw( (int) type, &outMetadata);
+    _hidl_cb(status, outMetadata);
+    return Void();
+}
+
+Status CameraDeviceSession::constructDefaultRequestSettingsRaw(int type, CameraMetadata *outMetadata) {
+    Status status = initStatus();
     const camera_metadata_t *rawRequest;
     if (status == Status::OK) {
         ATRACE_BEGIN("camera3->construct_default_request_settings");
@@ -761,15 +767,14 @@
                         defaultBoost, 1);
                 const camera_metadata_t *metaBuffer =
                         mOverridenRequest.getAndLock();
-                convertToHidl(metaBuffer, &outMetadata);
+                convertToHidl(metaBuffer, outMetadata);
                 mOverridenRequest.unlock(metaBuffer);
             } else {
-                convertToHidl(rawRequest, &outMetadata);
+                convertToHidl(rawRequest, outMetadata);
             }
         }
     }
-    _hidl_cb(status, outMetadata);
-    return Void();
+    return status;
 }
 
 /**
diff --git a/camera/device/3.2/default/CameraDeviceSession.h b/camera/device/3.2/default/CameraDeviceSession.h
index 0048ef4..dd73b39 100644
--- a/camera/device/3.2/default/CameraDeviceSession.h
+++ b/camera/device/3.2/default/CameraDeviceSession.h
@@ -112,7 +112,9 @@
     Return<Status> flush();
     Return<void> close();
 
-    //Helper methods
+    // Helper methods
+    Status constructDefaultRequestSettingsRaw(int type, CameraMetadata *outMetadata);
+
     bool preProcessConfigurationLocked(const StreamConfiguration& requestedConfiguration,
             camera3_stream_configuration_t *stream_list /*out*/,
             hidl_vec<camera3_stream_t*> *streams /*out*/);
diff --git a/camera/device/3.4/Android.bp b/camera/device/3.4/Android.bp
index 67b79b9..b3757c0 100644
--- a/camera/device/3.4/Android.bp
+++ b/camera/device/3.4/Android.bp
@@ -18,8 +18,11 @@
         "android.hidl.base@1.0",
     ],
     types: [
+        "CaptureRequest",
         "HalStream",
         "HalStreamConfiguration",
+        "PhysicalCameraSetting",
+        "RequestTemplate",
         "Stream",
         "StreamConfiguration",
     ],
diff --git a/camera/device/3.4/ICameraDeviceSession.hal b/camera/device/3.4/ICameraDeviceSession.hal
index 4ce749d..7afcf94 100644
--- a/camera/device/3.4/ICameraDeviceSession.hal
+++ b/camera/device/3.4/ICameraDeviceSession.hal
@@ -17,6 +17,7 @@
 package android.hardware.camera.device@3.4;
 
 import android.hardware.camera.common@1.0::Status;
+import @3.2::CameraMetadata;
 import @3.3::ICameraDeviceSession;
 import @3.3::HalStreamConfiguration;
 import @3.2::BufferCache;
@@ -30,6 +31,43 @@
 interface ICameraDeviceSession extends @3.3::ICameraDeviceSession {
 
     /**
+     * constructDefaultRequestSettings_3_4:
+     *
+     * Create capture settings for standard camera use cases. Supports the
+     * new template enums added in @3.4.
+     *
+     * The device must return a settings buffer that is configured to meet the
+     * requested use case, which must be one of the CAMERA3_TEMPLATE_*
+     * enums. All request control fields must be included.
+     *
+     * Performance requirements:
+     *
+     * This must be a non-blocking call. The HAL should return from this call
+     * in 1ms, and must return from this call in 5ms.
+     *
+     * Return values:
+     * @return status Status code for the operation, one of:
+     *     OK:
+     *         On a successful construction of default settings.
+     *     INTERNAL_ERROR:
+     *         An unexpected internal error occurred, and the default settings
+     *         are not available.
+     *     ILLEGAL_ARGUMENT:
+     *         The camera HAL does not support the input template type
+     *     CAMERA_DISCONNECTED:
+     *         An external camera device has been disconnected, and is no longer
+     *         available. This camera device interface is now stale, and a new
+     *         instance must be acquired if the device is reconnected. All
+     *         subsequent calls on this interface must return
+     *         CAMERA_DISCONNECTED.
+     * @return requestTemplate The default capture request settings for the requested
+     *     use case, or an empty metadata structure if status is not OK.
+     *
+     */
+    constructDefaultRequestSettings_3_4(RequestTemplate type) generates
+            (Status status, @3.2::CameraMetadata requestTemplate);
+
+    /**
      * configureStreams_3_4:
      *
      * Identical to @3.3::ICameraDeviceSession.configureStreams, except that:
diff --git a/camera/device/3.4/default/CameraDeviceSession.cpp b/camera/device/3.4/default/CameraDeviceSession.cpp
index c8d33eb..d054788 100644
--- a/camera/device/3.4/default/CameraDeviceSession.cpp
+++ b/camera/device/3.4/default/CameraDeviceSession.cpp
@@ -40,6 +40,14 @@
 CameraDeviceSession::~CameraDeviceSession() {
 }
 
+Return<void> CameraDeviceSession::constructDefaultRequestSettings_3_4(
+        RequestTemplate type, ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)  {
+    V3_2::CameraMetadata outMetadata;
+    Status status = constructDefaultRequestSettingsRaw( (int) type, &outMetadata);
+    _hidl_cb(status, outMetadata);
+    return Void();
+}
+
 Return<void> CameraDeviceSession::configureStreams_3_4(
         const StreamConfiguration& requestedConfiguration,
         ICameraDeviceSession::configureStreams_3_4_cb _hidl_cb)  {
diff --git a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
index 9589782..507f092 100644
--- a/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
+++ b/camera/device/3.4/default/ExternalCameraDeviceSession.cpp
@@ -178,33 +178,53 @@
 }
 
 Return<void> ExternalCameraDeviceSession::constructDefaultRequestSettings(
+        V3_2::RequestTemplate type,
+        V3_2::ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) {
+    V3_2::CameraMetadata outMetadata;
+    Status status = constructDefaultRequestSettingsRaw(
+            static_cast<RequestTemplate>(type), &outMetadata);
+    _hidl_cb(status, outMetadata);
+    return Void();
+}
+
+Return<void> ExternalCameraDeviceSession::constructDefaultRequestSettings_3_4(
         RequestTemplate type,
-        ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) {
+        ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb)  {
+    V3_2::CameraMetadata outMetadata;
+    Status status = constructDefaultRequestSettingsRaw(type, &outMetadata);
+    _hidl_cb(status, outMetadata);
+    return Void();
+}
+
+Status ExternalCameraDeviceSession::constructDefaultRequestSettingsRaw(RequestTemplate type,
+        V3_2::CameraMetadata *outMetadata) {
     CameraMetadata emptyMd;
     Status status = initStatus();
     if (status != Status::OK) {
-        _hidl_cb(status, emptyMd);
-        return Void();
+        return status;
     }
 
     switch (type) {
         case RequestTemplate::PREVIEW:
         case RequestTemplate::STILL_CAPTURE:
         case RequestTemplate::VIDEO_RECORD:
-        case RequestTemplate::VIDEO_SNAPSHOT:
-            _hidl_cb(Status::OK, mDefaultRequests[static_cast<int>(type)]);
+        case RequestTemplate::VIDEO_SNAPSHOT: {
+            *outMetadata = mDefaultRequests[type];
             break;
+        }
         case RequestTemplate::MANUAL:
         case RequestTemplate::ZERO_SHUTTER_LAG:
-            // Don't support MANUAL or ZSL template
-            _hidl_cb(Status::ILLEGAL_ARGUMENT, emptyMd);
+        case RequestTemplate::MOTION_TRACKING_PREVIEW:
+        case RequestTemplate::MOTION_TRACKING_BEST:
+            // Don't support MANUAL, ZSL, MOTION_TRACKING_* templates
+            status = Status::ILLEGAL_ARGUMENT;
             break;
         default:
             ALOGE("%s: unknown request template type %d", __FUNCTION__, static_cast<int>(type));
-            _hidl_cb(Status::ILLEGAL_ARGUMENT, emptyMd);
+            status = Status::ILLEGAL_ARGUMENT;
             break;
     }
-    return Void();
+    return status;
 }
 
 Return<void> ExternalCameraDeviceSession::configureStreams(
@@ -1767,21 +1787,21 @@
     const uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO;
     UPDATE(md, ANDROID_CONTROL_MODE, &controlMode, 1);
 
-    for (int type = static_cast<int>(RequestTemplate::PREVIEW);
-            type <= static_cast<int>(RequestTemplate::VIDEO_SNAPSHOT); type++) {
+    auto requestTemplates = hidl_enum_iterator<RequestTemplate>();
+    for (RequestTemplate type : requestTemplates) {
         ::android::hardware::camera::common::V1_0::helper::CameraMetadata mdCopy = md;
         uint8_t intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
         switch (type) {
-            case static_cast<int>(RequestTemplate::PREVIEW):
+            case RequestTemplate::PREVIEW:
                 intent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW;
                 break;
-            case static_cast<int>(RequestTemplate::STILL_CAPTURE):
+            case RequestTemplate::STILL_CAPTURE:
                 intent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE;
                 break;
-            case static_cast<int>(RequestTemplate::VIDEO_RECORD):
+            case RequestTemplate::VIDEO_RECORD:
                 intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD;
                 break;
-            case static_cast<int>(RequestTemplate::VIDEO_SNAPSHOT):
+            case RequestTemplate::VIDEO_SNAPSHOT:
                 intent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT;
                 break;
             default:
@@ -1987,4 +2007,3 @@
 }  // namespace camera
 }  // namespace hardware
 }  // namespace android
-
diff --git a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
index fbde083..913bd78 100644
--- a/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
+++ b/camera/device/3.4/default/include/device_v3_4_impl/CameraDeviceSession.h
@@ -73,6 +73,9 @@
     // Methods from v3.3 and earlier will trampoline to inherited implementation
 
     // New methods for v3.4
+    Return<void> constructDefaultRequestSettings_3_4(
+            RequestTemplate type,
+            ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb);
 
     Return<void> configureStreams_3_4(
             const StreamConfiguration& requestedConfiguration,
@@ -139,6 +142,12 @@
             return mParent->close();
         }
 
+        virtual Return<void> constructDefaultRequestSettings_3_4(
+                RequestTemplate type,
+                ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
+            return mParent->constructDefaultRequestSettings_3_4(type, _hidl_cb);
+        }
+
         virtual Return<void> configureStreams_3_3(
                 const V3_2::StreamConfiguration& requestedConfiguration,
                 configureStreams_3_3_cb _hidl_cb) override {
diff --git a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
index 404dfe0..d8a17f6 100644
--- a/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
+++ b/camera/device/3.4/default/include/ext_device_v3_4_impl/ExternalCameraDeviceSession.h
@@ -51,7 +51,7 @@
 using ::android::hardware::camera::device::V3_2::ICameraDeviceCallback;
 using ::android::hardware::camera::device::V3_2::MsgType;
 using ::android::hardware::camera::device::V3_2::NotifyMsg;
-using ::android::hardware::camera::device::V3_2::RequestTemplate;
+using ::android::hardware::camera::device::V3_4::RequestTemplate;
 using ::android::hardware::camera::device::V3_2::Stream;
 using ::android::hardware::camera::device::V3_4::StreamConfiguration;
 using ::android::hardware::camera::device::V3_2::StreamConfigurationMode;
@@ -172,7 +172,11 @@
     // Methods from ::android::hardware::camera::device::V3_2::ICameraDeviceSession follow
 
     Return<void> constructDefaultRequestSettings(
-            RequestTemplate,
+            V3_2::RequestTemplate,
+            ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb);
+
+    Return<void> constructDefaultRequestSettings_3_4(
+            RequestTemplate type,
             ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb);
 
     Return<void> configureStreams(
@@ -227,6 +231,9 @@
         std::vector<HalStreamBuffer> buffers;
     };
 
+    Status constructDefaultRequestSettingsRaw(RequestTemplate type,
+            V3_2::CameraMetadata *outMetadata);
+
     static std::vector<SupportedV4L2Format> sortFormats(
             const std::vector<SupportedV4L2Format>&);
     static CroppingType initCroppingType(const std::vector<SupportedV4L2Format>&);
@@ -363,7 +370,7 @@
     // Protect against invokeProcessCaptureResultCallback()
     Mutex mProcessCaptureResultLock;
 
-    std::unordered_map<int, CameraMetadata> mDefaultRequests;
+    std::unordered_map<RequestTemplate, CameraMetadata> mDefaultRequests;
     /* End of members not changed after initialize() */
 
 private:
@@ -408,6 +415,12 @@
             return mParent->close();
         }
 
+        virtual Return<void> constructDefaultRequestSettings_3_4(
+                RequestTemplate type,
+                ICameraDeviceSession::constructDefaultRequestSettings_cb _hidl_cb) override {
+            return mParent->constructDefaultRequestSettings_3_4(type, _hidl_cb);
+        }
+
         virtual Return<void> configureStreams_3_3(
                 const V3_2::StreamConfiguration& requestedConfiguration,
                 configureStreams_3_3_cb _hidl_cb) override {
diff --git a/camera/device/3.4/types.hal b/camera/device/3.4/types.hal
index 77e855f..429db3e 100644
--- a/camera/device/3.4/types.hal
+++ b/camera/device/3.4/types.hal
@@ -16,7 +16,7 @@
 
 package android.hardware.camera.device@3.4;
 
-import @3.2::types;
+import @3.2::RequestTemplate;
 import @3.2::StreamConfigurationMode;
 import @3.2::Stream;
 import @3.3::HalStream;
@@ -62,6 +62,36 @@
 };
 
 /**
+ * New request templates, extending the @3.2 RequestTemplate
+ */
+enum RequestTemplate : @3.2::RequestTemplate {
+    /**
+     * A template for selecting camera parameters that match TEMPLATE_PREVIEW as closely as
+     * possible while improving the camera output for motion tracking use cases.
+     *
+     * This template is best used by applications that are frequently switching between motion
+     * tracking use cases and regular still capture use cases, to minimize the IQ changes
+     * when swapping use cases.
+     *
+     * This template is guaranteed to be supported on camera devices that support the
+     * REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING capability.
+     */
+    MOTION_TRACKING_PREVIEW = 7,
+
+    /**
+     * A template for selecting camera parameters that maximize the quality of camera output for
+     * motion tracking use cases.
+     *
+     * This template is best used by applications dedicated to motion tracking applications,
+     * which aren't concerned about fast switches between motion tracking and other use cases.
+     *
+     * This template is guaranteed to be supported on camera devices that support the
+     * REQUEST_AVAILABLE_CAPABILITIES_MOTION_TRACKING capability.
+     */
+    MOTION_TRACKING_BEST = 8,
+};
+
+/**
  * StreamConfiguration:
  *
  * Identical to @3.2::StreamConfiguration, except that it contains session
diff --git a/camera/metadata/3.3/Android.bp b/camera/metadata/3.3/Android.bp
index 23c1036..166c2ac 100644
--- a/camera/metadata/3.3/Android.bp
+++ b/camera/metadata/3.3/Android.bp
@@ -13,11 +13,14 @@
         "android.hardware.camera.metadata@3.2",
     ],
     types: [
+        "CameraMetadataEnumAndroidControlAeMode",
         "CameraMetadataEnumAndroidControlAfSceneChange",
         "CameraMetadataEnumAndroidControlCaptureIntent",
+        "CameraMetadataEnumAndroidInfoSupportedHardwareLevel",
         "CameraMetadataEnumAndroidLensPoseReference",
-        "CameraMetadataEnumAndroidRequestAvailableCapabilities",
         "CameraMetadataEnumAndroidLogicalMultiCameraSensorSyncType",
+        "CameraMetadataEnumAndroidRequestAvailableCapabilities",
+        "CameraMetadataEnumAndroidStatisticsOisDataMode",
         "CameraMetadataSection",
         "CameraMetadataSectionStart",
         "CameraMetadataTag",
diff --git a/health/2.0/Android.bp b/health/2.0/Android.bp
index c444165..0325467 100644
--- a/health/2.0/Android.bp
+++ b/health/2.0/Android.bp
@@ -16,9 +16,9 @@
         "android.hidl.base@1.0",
     ],
     types: [
-        "Result",
         "DiskStats",
         "HealthInfo",
+        "Result",
         "StorageAttribute",
         "StorageInfo",
     ],
diff --git a/keymaster/4.0/Android.bp b/keymaster/4.0/Android.bp
index 20c40a0..2daad41 100644
--- a/keymaster/4.0/Android.bp
+++ b/keymaster/4.0/Android.bp
@@ -15,16 +15,26 @@
         "android.hidl.base@1.0",
     ],
     types: [
+        "Algorithm",
+        "BlockMode",
         "Constants",
+        "Digest",
+        "EcCurve",
         "ErrorCode",
         "HardwareAuthToken",
+        "HardwareAuthenticatorType",
         "HmacSharingParameters",
+        "KeyBlobUsageRequirements",
         "KeyCharacteristics",
+        "KeyDerivationFunction",
+        "KeyFormat",
         "KeyOrigin",
         "KeyParameter",
         "KeyPurpose",
+        "PaddingMode",
         "SecurityLevel",
         "Tag",
+        "TagType",
         "VerificationToken",
     ],
     gen_java: false,
diff --git a/keymaster/4.0/IKeymasterDevice.hal b/keymaster/4.0/IKeymasterDevice.hal
index 5dac929..aef81c7 100644
--- a/keymaster/4.0/IKeymasterDevice.hal
+++ b/keymaster/4.0/IKeymasterDevice.hal
@@ -374,10 +374,27 @@
     /**
      * Upgrades an old key blob.  Keys can become "old" in two ways: Keymaster can be upgraded to a
      * new version with an incompatible key blob format, or the system can be updated to invalidate
-     * the OS version and/or patch level.  In either case, attempts to use an old key blob with
-     * getKeyCharacteristics(), exportKey(), attestKey() or begin() must result in Keymaster
-     * returning ErrorCode::KEY_REQUIRES_UPGRADE.  The caller must use this method to upgrade the
-     * key blob.
+     * the OS version (OS_VERSION tag), system patch level (OS_PATCHLEVEL tag), vendor patch level
+     * (VENDOR_PATCH_LEVEL tag), boot patch level (BOOT_PATCH_LEVEL tag) or other,
+     * implementation-defined patch level (keymaster implementers are encouraged to extend this HAL
+     * with a minor version extension to define validatable patch levels for other images; tags
+     * must be defined in the implemeter's namespace, starting at 10000).  In either case,
+     * attempts to use an old key blob with getKeyCharacteristics(), exportKey(), attestKey() or
+     * begin() must result in Keymaster returning ErrorCode::KEY_REQUIRES_UPGRADE.  The caller must
+     * use this method to upgrade the key blob.
+     *
+     * If upgradeKey is asked to update a key with any version or patch level that is higher than
+     * the current system version or patch level, it must return ErrorCode::INVALID_ARGUMENT.  There
+     * is one exception: it is always permissible to "upgrade" from any OS_VERSION number to
+     * OS_VERSION 0.  For example, if the key has OS_VERSION 080001, it is permisible to upgrade the
+     * key if the current system version is 080100, because the new version is larger, or if the
+     * current system version is 0, because upgrades to 0 are always allowed.  If the system version
+     * were 080000, however, keymaster must return ErrorCode::INVALID_ARGUMENT because that value is
+     * smaller than 080001.
+     *
+     * Note that Keymaster versions 2 and 3 required that the system and boot images have the same
+     * patch level and OS version.  This requirement is relaxed for Keymaster 4, and the OS version
+     * in the boot image footer is no longer used.
      *
      * @param keyBlobToUpgrade The opaque descriptor returned by generateKey() or importKey();
      *
diff --git a/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h b/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
index 73e03fb..0dfc735 100644
--- a/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
+++ b/keymaster/4.0/support/include/keymasterV4_0/keymaster_tags.h
@@ -356,6 +356,8 @@
         case Tag::OS_PATCHLEVEL:
         case Tag::MAC_LENGTH:
         case Tag::AUTH_TIMEOUT:
+        case Tag::VENDOR_PATCHLEVEL:
+        case Tag::BOOT_PATCHLEVEL:
             return a.f.integer == b.f.integer;
 
         /* Long integer tags */
diff --git a/keymaster/4.0/types.hal b/keymaster/4.0/types.hal
index e890c6d..5714c4d 100644
--- a/keymaster/4.0/types.hal
+++ b/keymaster/4.0/types.hal
@@ -219,6 +219,30 @@
     ATTESTATION_ID_MODEL = TagType:BYTES | 717, /* Used to provide the device's model name to be
                                                  * included in attestation */
 
+    /**
+     * Patch level of vendor image.  The value is an integer of the form YYYYMM, where YYYY is the
+     * four-digit year when the vendor image was released and MM is the two-digit month.  During
+     * each boot, the bootloader must provide the patch level of the vendor image to keymaser
+     * (mechanism is implemntation-defined).  When keymaster keys are created or updated, the
+     * VENDOR_PATCHLEVEL tag must be cryptographically bound to the keys, with the current value as
+     * provided by the bootloader.  When keys are used, keymaster must verify that the
+     * VENDOR_PATCHLEVEL bound to the key matches the current value.  If they do not match,
+     * keymaster must return ErrorCode::KEY_REQUIRES_UPGRADE.  The client must then call upgradeKey.
+     */
+    VENDOR_PATCHLEVEL = TagType:UINT | 718,
+
+    /**
+     * Patch level of boot image.  The value is an integer of the form YYYYMM, where YYYY is the
+     * four-digit year when the boot image was released and MM is the two-digit month.  During each
+     * boot, the bootloader must provide the patch level of the boot image to keymaser (mechanism is
+     * implemntation-defined).  When keymaster keys are created or updated, the BOOT_PATCHLEVEL tag
+     * must be cryptographically bound to the keys, with the current value as provided by the
+     * bootloader.  When keys are used, keymaster must verify that the BOOT_PATCHLEVEL bound to the
+     * key matches the current value.  If they do not match, keymaster must return
+     * ErrorCode::KEY_REQUIRES_UPGRADE.  The client must then call upgradeKey.
+     */
+    BOOT_PATCHLEVEL = TagType:UINT | 719,
+
     /* Tags used only to provide data to or receive data from operations */
     ASSOCIATED_DATA = TagType:BYTES | 1000, /* Used to provide associated data for AEAD modes. */
     NONCE = TagType:BYTES | 1001,           /* Nonce or Initialization Vector */
diff --git a/light/utils/blank_screen.rc b/light/utils/blank_screen.rc
index 735551c..7b2a55e 100644
--- a/light/utils/blank_screen.rc
+++ b/light/utils/blank_screen.rc
@@ -1,5 +1,5 @@
 service blank_screen /system/bin/blank_screen
     user system
     oneshot
-    group system readproc
+    group system
     shutdown critical
diff --git a/radio/config/1.0/default/Android.bp b/radio/config/1.0/default/Android.bp
new file mode 100644
index 0000000..f52335e
--- /dev/null
+++ b/radio/config/1.0/default/Android.bp
@@ -0,0 +1,20 @@
+cc_binary {
+    name: "android.hardware.radio.config@1.0-service",
+    init_rc: ["android.hardware.radio.config@1.0-service.rc"],
+    relative_install_path: "hw",
+    vendor: true,
+    srcs: [
+        "RadioConfig.cpp",
+        "RadioConfigIndication.cpp",
+        "RadioConfigResponse.cpp",
+        "service.cpp",
+    ],
+    shared_libs: [
+        "libhidlbase",
+        "libhidltransport",
+        "liblog",
+        "libutils",
+        "android.hardware.radio.config@1.0",
+        "android.hardware.radio@1.0",
+    ],
+}
diff --git a/radio/config/1.0/default/RadioConfig.cpp b/radio/config/1.0/default/RadioConfig.cpp
new file mode 100644
index 0000000..af4b77e
--- /dev/null
+++ b/radio/config/1.0/default/RadioConfig.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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 "RadioConfig.h"
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_0 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::config::V1_0;
+
+// Methods from ::android::hardware::radio::config::V1_0::IRadioConfig follow.
+Return<void> RadioConfig::setResponseFunctions(
+    const sp<IRadioConfigResponse>& radioConfigResponse,
+    const sp<IRadioConfigIndication>& radioConfigIndication) {
+    mRadioConfigResponse = radioConfigResponse;
+    mRadioConfigIndication = radioConfigIndication;
+    return Void();
+}
+
+Return<void> RadioConfig::getSimSlotsStatus(int32_t /* serial */) {
+    hidl_vec<SimSlotStatus> slotStatus;
+    ::android::hardware::radio::V1_0::RadioResponseInfo info;
+    mRadioConfigResponse->getSimSlotsStatusResponse(info, slotStatus);
+    return Void();
+}
+
+Return<void> RadioConfig::setSimSlotsMapping(int32_t /* serial */,
+                                             const hidl_vec<uint32_t>& /* slotMap */) {
+    ::android::hardware::radio::V1_0::RadioResponseInfo info;
+    mRadioConfigResponse->setSimSlotsMappingResponse(info);
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace config
+}  // namespace radio
+}  // namespace hardware
+}  // namespace android
diff --git a/radio/config/1.0/default/RadioConfig.h b/radio/config/1.0/default/RadioConfig.h
new file mode 100644
index 0000000..0f0ac75
--- /dev/null
+++ b/radio/config/1.0/default/RadioConfig.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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_HARDWARE_RADIO_CONFIG_V1_0_RADIOCONFIG_H
+#define ANDROID_HARDWARE_RADIO_CONFIG_V1_0_RADIOCONFIG_H
+
+#include <android/hardware/radio/config/1.0/IRadioConfig.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct RadioConfig : public IRadioConfig {
+    sp<IRadioConfigResponse> mRadioConfigResponse;
+    sp<IRadioConfigIndication> mRadioConfigIndication;
+    // Methods from ::android::hardware::radio::config::V1_0::IRadioConfig follow.
+    Return<void> setResponseFunctions(
+        const sp<::android::hardware::radio::config::V1_0::IRadioConfigResponse>&
+            radioConfigResponse,
+        const sp<::android::hardware::radio::config::V1_0::IRadioConfigIndication>&
+            radioConfigIndication) override;
+    Return<void> getSimSlotsStatus(int32_t serial) override;
+    Return<void> setSimSlotsMapping(int32_t serial, const hidl_vec<uint32_t>& slotMap) override;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace config
+}  // namespace radio
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_RADIO_CONFIG_V1_0_RADIOCONFIG_H
diff --git a/radio/config/1.0/default/RadioConfigIndication.cpp b/radio/config/1.0/default/RadioConfigIndication.cpp
new file mode 100644
index 0000000..1005ca3
--- /dev/null
+++ b/radio/config/1.0/default/RadioConfigIndication.cpp
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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 "RadioConfigIndication.h"
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_0 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::V1_0;
+
+// Methods from ::android::hardware::radio::config::V1_0::IRadioConfigIndication follow.
+Return<void> RadioConfigIndication::simSlotsStatusChanged(
+    RadioIndicationType /* type */, const hidl_vec<SimSlotStatus>& /* slotStatus */) {
+    // TODO implement
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace config
+}  // namespace radio
+}  // namespace hardware
+}  // namespace android
diff --git a/radio/config/1.0/default/RadioConfigIndication.h b/radio/config/1.0/default/RadioConfigIndication.h
new file mode 100644
index 0000000..cfab1e6
--- /dev/null
+++ b/radio/config/1.0/default/RadioConfigIndication.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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_HARDWARE_RADIO_CONFIG_V1_0_RADIOCONFIGINDICATION_H
+#define ANDROID_HARDWARE_RADIO_CONFIG_V1_0_RADIOCONFIGINDICATION_H
+
+#include <android/hardware/radio/config/1.0/IRadioConfigIndication.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct RadioConfigIndication : public IRadioConfigIndication {
+    // Methods from ::android::hardware::radio::config::V1_0::IRadioConfigIndication follow.
+    Return<void> simSlotsStatusChanged(
+        ::android::hardware::radio::V1_0::RadioIndicationType type,
+        const hidl_vec<::android::hardware::radio::config::V1_0::SimSlotStatus>& slotStatus)
+        override;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace config
+}  // namespace radio
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_RADIO_CONFIG_V1_0_RADIOCONFIGINDICATION_H
diff --git a/radio/config/1.0/default/RadioConfigResponse.cpp b/radio/config/1.0/default/RadioConfigResponse.cpp
new file mode 100644
index 0000000..029eab2
--- /dev/null
+++ b/radio/config/1.0/default/RadioConfigResponse.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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 "RadioConfigResponse.h"
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_0 {
+namespace implementation {
+
+using namespace ::android::hardware::radio::V1_0;
+using namespace ::android::hardware::radio::config::V1_0;
+
+// Methods from ::android::hardware::radio::config::V1_0::IRadioConfigResponse follow.
+Return<void> RadioConfigResponse::getSimSlotsStatusResponse(
+    const RadioResponseInfo& /* info */, const hidl_vec<SimSlotStatus>& /* slotStatus */) {
+    // TODO implement
+    return Void();
+}
+
+Return<void> RadioConfigResponse::setSimSlotsMappingResponse(const RadioResponseInfo& /* info */) {
+    // TODO implement
+    return Void();
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace config
+}  // namespace radio
+}  // namespace hardware
+}  // namespace android
diff --git a/radio/config/1.0/default/RadioConfigResponse.h b/radio/config/1.0/default/RadioConfigResponse.h
new file mode 100644
index 0000000..7d121fd
--- /dev/null
+++ b/radio/config/1.0/default/RadioConfigResponse.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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_HARDWARE_RADIO_CONFIG_V1_0_RADIOCONFIGRESPONSE_H
+#define ANDROID_HARDWARE_RADIO_CONFIG_V1_0_RADIOCONFIGRESPONSE_H
+
+#include <android/hardware/radio/config/1.0/IRadioConfigResponse.h>
+#include <hidl/MQDescriptor.h>
+#include <hidl/Status.h>
+
+namespace android {
+namespace hardware {
+namespace radio {
+namespace config {
+namespace V1_0 {
+namespace implementation {
+
+using ::android::hardware::hidl_array;
+using ::android::hardware::hidl_memory;
+using ::android::hardware::hidl_string;
+using ::android::hardware::hidl_vec;
+using ::android::hardware::Return;
+using ::android::hardware::Void;
+using ::android::sp;
+
+struct RadioConfigResponse : public IRadioConfigResponse {
+    // Methods from ::android::hardware::radio::config::V1_0::IRadioConfigResponse follow.
+    Return<void> getSimSlotsStatusResponse(
+        const ::android::hardware::radio::V1_0::RadioResponseInfo& info,
+        const hidl_vec<::android::hardware::radio::config::V1_0::SimSlotStatus>& slotStatus)
+        override;
+    Return<void> setSimSlotsMappingResponse(
+        const ::android::hardware::radio::V1_0::RadioResponseInfo& info) override;
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace config
+}  // namespace radio
+}  // namespace hardware
+}  // namespace android
+
+#endif  // ANDROID_HARDWARE_RADIO_CONFIG_V1_0_RADIOCONFIGRESPONSE_H
diff --git a/radio/config/1.0/default/android.hardware.radio.config@1.0-service.rc b/radio/config/1.0/default/android.hardware.radio.config@1.0-service.rc
new file mode 100644
index 0000000..fad16b1
--- /dev/null
+++ b/radio/config/1.0/default/android.hardware.radio.config@1.0-service.rc
@@ -0,0 +1,4 @@
+service vendor.radio-config-hal-1-0 /vendor/bin/hw/android.hardware.radio.config@1.0-service
+    class hal
+    user system
+    group system
diff --git a/radio/config/1.0/default/service.cpp b/radio/config/1.0/default/service.cpp
new file mode 100644
index 0000000..a06cc22
--- /dev/null
+++ b/radio/config/1.0/default/service.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.1 (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.1
+ *
+ * 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 LOG_TAG "android.hardware.radio.config@1.0-service"
+
+#include <android/hardware/radio/config/1.0/IRadioConfig.h>
+#include <hidl/HidlTransportSupport.h>
+
+#include "RadioConfig.h"
+
+using android::hardware::configureRpcThreadpool;
+using android::hardware::joinRpcThreadpool;
+using android::hardware::radio::config::V1_0::IRadioConfig;
+using android::hardware::radio::config::V1_0::implementation::RadioConfig;
+using android::sp;
+using android::status_t;
+using android::OK;
+
+int main() {
+    configureRpcThreadpool(1, true);
+
+    sp<IRadioConfig> radioConfig = new RadioConfig;
+    status_t status = radioConfig->registerAsService();
+    ALOGW_IF(status != OK, "Could not register IRadioConfig");
+    ALOGD("Default service is ready.");
+
+    joinRpcThreadpool();
+    return 0;
+}
\ No newline at end of file
diff --git a/usb/gadget/1.0/Android.bp b/usb/gadget/1.0/Android.bp
new file mode 100644
index 0000000..f38002f
--- /dev/null
+++ b/usb/gadget/1.0/Android.bp
@@ -0,0 +1,23 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+    name: "android.hardware.usb.gadget@1.0",
+    root: "android.hardware",
+    vndk: {
+        enabled: true,
+    },
+    srcs: [
+        "types.hal",
+        "IUsbGadget.hal",
+        "IUsbGadgetCallback.hal",
+    ],
+    interfaces: [
+        "android.hidl.base@1.0",
+    ],
+    types: [
+        "GadgetFunction",
+        "Status",
+    ],
+    gen_java: true,
+}
+
diff --git a/usb/gadget/1.0/IUsbGadget.hal b/usb/gadget/1.0/IUsbGadget.hal
new file mode 100644
index 0000000..41be401
--- /dev/null
+++ b/usb/gadget/1.0/IUsbGadget.hal
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.hardware.usb.gadget@1.0;
+
+import IUsbGadgetCallback;
+
+interface IUsbGadget {
+    /**
+     * This function is used to set the current USB gadget configuration.
+     * Usb gadget needs to teared down if an USB configuration is already
+     * active.
+     *
+     * @param functions list of functions defined by GadgetFunction to be
+     *                  included in the gadget composition.
+     * @param callback IUsbGadgetCallback::setCurrentUsbFunctionsCb used to
+     *                 propagate back the status.
+     * @param timeout The maximum time (in milliseconds) within which the
+     *                IUsbGadgetCallback needs to be returned.
+     */
+    oneway setCurrentUsbFunctions(bitfield<GadgetFunction> functions,
+                                  IUsbGadgetCallback callback,
+                                  uint64_t timeout);
+
+    /**
+     * This function is used to query the USB functions included in the
+     * current USB configuration.
+     *
+     * @param callback IUsbGadgetCallback::getCurrentUsbFunctionsCb used to
+     *                 propagate the current functions list.
+     */
+    oneway getCurrentUsbFunctions(IUsbGadgetCallback callback);
+
+};
diff --git a/usb/gadget/1.0/IUsbGadgetCallback.hal b/usb/gadget/1.0/IUsbGadgetCallback.hal
new file mode 100644
index 0000000..8876abb
--- /dev/null
+++ b/usb/gadget/1.0/IUsbGadgetCallback.hal
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.hardware.usb.gadget@1.0;
+
+interface IUsbGadgetCallback {
+    /**
+     * Callback function used to propagate the status of configuration
+     * switch to the caller.
+     *
+     * @param functions list of functions defined by GadgetFunction
+     *                  included in the current USB gadget composition.
+     * @param status SUCCESS when the functions are applied.
+     *               FUNCTIONS_NOT_SUPPORTED when the configuration is
+     *                                       not supported.
+     *               ERROR otherwise.
+     */
+    oneway setCurrentUsbFunctionsCb(bitfield<GadgetFunction> functions,
+                                    Status status);
+
+    /**
+     * Callback function used to propagate the current USB gadget
+     * configuration.
+     * @param functions list of functions defined by GadgetFunction
+     *                  included in the current USB gadget composition.
+     * @param status FUNCTIONS_APPLIED when list of functions have been
+     *                                 applied.
+     *               FUNCTIONS_NOT_APPLIED when the functions have not
+     *                                     been applied.
+     *               ERROR otherwise.
+     */
+    oneway getCurrentUsbFunctionsCb(bitfield<GadgetFunction> functions,
+                                    Status status);
+};
diff --git a/usb/gadget/1.0/types.hal b/usb/gadget/1.0/types.hal
new file mode 100644
index 0000000..3793fe2
--- /dev/null
+++ b/usb/gadget/1.0/types.hal
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+package android.hardware.usb.gadget@1.0;
+
+enum GadgetFunction : uint64_t {
+    /**
+     * Removes all the functions and pulls down the gadget.
+     */
+    NONE = 0,
+
+    /**
+     * Android Debug Bridge function.
+     */
+    ADB = 1 << 0,
+
+    /**
+     * Android open accessory protocol function.
+     */
+    ACCESSORY = 1 << 1,
+
+    /**
+     * Media Transfer protocol function.
+     */
+    MTP = 1 << 2,
+
+    /**
+     * Peripheral mode USB Midi function.
+     */
+    MIDI = 1 << 3,
+
+    /**
+     * Picture transfer protocol function.
+     */
+    PTP = 1 << 4,
+
+    /**
+     * Tethering function.
+     */
+    RNDIS = 1 << 5,
+
+    /**
+     * AOAv2.0 - Audio Source function.
+     */
+    AUDIO_SOURCE = 1 << 6,
+};
+
+enum Status : uint32_t {
+    SUCCESS = 0,
+
+    /**
+     * Error value when the HAL operation fails for reasons not listed here.
+     */
+    ERROR = 1,
+
+    /**
+     * USB configuration applied successfully.
+     */
+    FUNCTIONS_APPLIED = 2,
+
+    /**
+     * USB confgiuration failed to apply.
+     */
+    FUNCTIONS_NOT_APPLIED = 3,
+
+    /**
+     * USB configuration not supported.
+     */
+    CONFIGURATION_NOT_SUPPORTED = 4,
+};
diff --git a/wifi/1.2/default/Android.mk b/wifi/1.2/default/Android.mk
index 95414bc..8d0262b 100644
--- a/wifi/1.2/default/Android.mk
+++ b/wifi/1.2/default/Android.mk
@@ -30,6 +30,7 @@
 LOCAL_SRC_FILES := \
     hidl_struct_util.cpp \
     hidl_sync_util.cpp \
+    ringbuffer.cpp \
     wifi.cpp \
     wifi_ap_iface.cpp \
     wifi_chip.cpp \
@@ -97,6 +98,7 @@
     tests/mock_wifi_feature_flags.cpp \
     tests/mock_wifi_legacy_hal.cpp \
     tests/mock_wifi_mode_controller.cpp \
+    tests/ringbuffer_unit_tests.cpp \
     tests/wifi_chip_unit_tests.cpp
 LOCAL_STATIC_LIBRARIES := \
     libgmock \
diff --git a/wifi/1.2/default/ringbuffer.cpp b/wifi/1.2/default/ringbuffer.cpp
new file mode 100644
index 0000000..5511f2f
--- /dev/null
+++ b/wifi/1.2/default/ringbuffer.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 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 "ringbuffer.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+
+Ringbuffer::Ringbuffer(size_t maxSize) : size_(0), maxSize_(maxSize) {}
+
+void Ringbuffer::append(const std::vector<uint8_t>& input) {
+    if (input.size() == 0) {
+        return;
+    }
+    data_.push_back(input);
+    size_ += input.size() * sizeof(input[0]);
+    while (size_ > maxSize_) {
+        size_ -= data_.front().size() * sizeof(data_.front()[0]);
+        data_.pop_front();
+    }
+}
+
+const std::list<std::vector<uint8_t>>& Ringbuffer::getData() const {
+    return data_;
+}
+
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.2/default/ringbuffer.h b/wifi/1.2/default/ringbuffer.h
new file mode 100644
index 0000000..4808e40
--- /dev/null
+++ b/wifi/1.2/default/ringbuffer.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2018 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 RINGBUFFER_H_
+#define RINGBUFFER_H_
+
+#include <list>
+#include <vector>
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+
+/**
+ * Ringbuffer object used to store debug data.
+ */
+class Ringbuffer {
+   public:
+    explicit Ringbuffer(size_t maxSize);
+
+    // Appends the data buffer and deletes from the front until buffer is
+    // within |maxSize_|.
+    void append(const std::vector<uint8_t>& input);
+    const std::list<std::vector<uint8_t>>& getData() const;
+
+   private:
+    std::list<std::vector<uint8_t>> data_;
+    size_t size_;
+    size_t maxSize_;
+};
+
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+
+#endif  // RINGBUFFER_H_
diff --git a/wifi/1.2/default/tests/ringbuffer_unit_tests.cpp b/wifi/1.2/default/tests/ringbuffer_unit_tests.cpp
new file mode 100644
index 0000000..1b332f9
--- /dev/null
+++ b/wifi/1.2/default/tests/ringbuffer_unit_tests.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2018, 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 <gmock/gmock.h>
+
+#include "ringbuffer.h"
+
+using testing::Return;
+using testing::Test;
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace V1_2 {
+namespace implementation {
+
+class RingbufferTest : public Test {
+   public:
+    const uint32_t maxBufferSize_ = 10;
+    Ringbuffer buffer_{maxBufferSize_};
+};
+
+TEST_F(RingbufferTest, CreateEmptyBuffer) {
+    ASSERT_TRUE(buffer_.getData().empty());
+}
+
+TEST_F(RingbufferTest, CanUseFullBufferCapacity) {
+    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
+    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
+    buffer_.append(input);
+    buffer_.append(input2);
+    ASSERT_EQ(2u, buffer_.getData().size());
+    EXPECT_EQ(input, buffer_.getData().front());
+    EXPECT_EQ(input2, buffer_.getData().back());
+}
+
+TEST_F(RingbufferTest, OldDataIsRemovedOnOverflow) {
+    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
+    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
+    const std::vector<uint8_t> input3 = {'G'};
+    buffer_.append(input);
+    buffer_.append(input2);
+    buffer_.append(input3);
+    ASSERT_EQ(2u, buffer_.getData().size());
+    EXPECT_EQ(input2, buffer_.getData().front());
+    EXPECT_EQ(input3, buffer_.getData().back());
+}
+
+TEST_F(RingbufferTest, MultipleOldDataIsRemovedOnOverflow) {
+    const std::vector<uint8_t> input(maxBufferSize_ / 2, '0');
+    const std::vector<uint8_t> input2(maxBufferSize_ / 2, '1');
+    const std::vector<uint8_t> input3(maxBufferSize_, '2');
+    buffer_.append(input);
+    buffer_.append(input2);
+    buffer_.append(input3);
+    ASSERT_EQ(1u, buffer_.getData().size());
+    EXPECT_EQ(input3, buffer_.getData().front());
+}
+
+TEST_F(RingbufferTest, AppendingEmptyBufferDoesNotAddGarbage) {
+    const std::vector<uint8_t> input = {};
+    buffer_.append(input);
+    ASSERT_TRUE(buffer_.getData().empty());
+}
+
+TEST_F(RingbufferTest, OversizedAppendIsDropped) {
+    const std::vector<uint8_t> input(maxBufferSize_ + 1, '0');
+    buffer_.append(input);
+    ASSERT_TRUE(buffer_.getData().empty());
+}
+}  // namespace implementation
+}  // namespace V1_2
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
diff --git a/wifi/1.2/default/wifi.cpp b/wifi/1.2/default/wifi.cpp
index 06f5058..d6106b4 100644
--- a/wifi/1.2/default/wifi.cpp
+++ b/wifi/1.2/default/wifi.cpp
@@ -77,6 +77,12 @@
                            &Wifi::getChipInternal, hidl_status_cb, chip_id);
 }
 
+Return<void> Wifi::debug(const hidl_handle& handle,
+                         const hidl_vec<hidl_string>&) {
+    LOG(INFO) << "-----------Debug is called----------------";
+    return chip_->debug(handle, {});
+}
+
 WifiStatus Wifi::registerEventCallbackInternal(
     const sp<IWifiEventCallback>& event_callback) {
     if (!event_cb_handler_.addCallback(event_callback)) {
diff --git a/wifi/1.2/default/wifi.h b/wifi/1.2/default/wifi.h
index 440c3c7..86919b1 100644
--- a/wifi/1.2/default/wifi.h
+++ b/wifi/1.2/default/wifi.h
@@ -56,6 +56,8 @@
     Return<void> stop(stop_cb hidl_status_cb) override;
     Return<void> getChipIds(getChipIds_cb hidl_status_cb) override;
     Return<void> getChip(ChipId chip_id, getChip_cb hidl_status_cb) override;
+    Return<void> debug(const hidl_handle& handle,
+                       const hidl_vec<hidl_string>& options) override;
 
    private:
     enum class RunState { STOPPED, STARTED, STOPPING };
diff --git a/wifi/1.2/default/wifi_chip.cpp b/wifi/1.2/default/wifi_chip.cpp
index 8d9cfc6..bc3404a 100644
--- a/wifi/1.2/default/wifi_chip.cpp
+++ b/wifi/1.2/default/wifi_chip.cpp
@@ -14,8 +14,13 @@
  * limitations under the License.
  */
 
+#include <fcntl.h>
+
 #include <android-base/logging.h>
+#include <android-base/unique_fd.h>
 #include <cutils/properties.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
 
 #include "hidl_return_util.h"
 #include "hidl_struct_util.h"
@@ -23,6 +28,7 @@
 #include "wifi_status_util.h"
 
 namespace {
+using android::base::unique_fd;
 using android::hardware::hidl_string;
 using android::hardware::hidl_vec;
 using android::hardware::wifi::V1_0::ChipModeId;
@@ -39,6 +45,11 @@
 // Mode ID for V2
 constexpr ChipModeId kV2ChipModeId = 2;
 
+constexpr char kCpioMagic[] = "070701";
+constexpr size_t kMaxBufferSizeBytes = 1024 * 1024;
+constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60;
+constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
+
 template <typename Iface>
 void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
     iface->invalidate();
@@ -93,6 +104,165 @@
     return buffer.data();
 }
 
+// delete files older than a predefined time in the wifi tombstone dir
+bool removeOldFilesInternal() {
+    time_t now = time(0);
+    const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
+    DIR* dir_dump = opendir(kTombstoneFolderPath);
+    if (!dir_dump) {
+        LOG(ERROR) << "Failed to open directory: " << strerror(errno);
+        return false;
+    }
+    unique_fd dir_auto_closer(dirfd(dir_dump));
+    struct dirent* dp;
+    bool success = true;
+    while ((dp = readdir(dir_dump))) {
+        if (dp->d_type != DT_REG) {
+            continue;
+        }
+        std::string cur_file_name(dp->d_name);
+        struct stat cur_file_stat;
+        std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
+        if (stat(cur_file_path.c_str(), &cur_file_stat) != -1) {
+            if (cur_file_stat.st_mtime < delete_files_before) {
+                if (unlink(cur_file_path.c_str()) != 0) {
+                    LOG(ERROR) << "Error deleting file " << strerror(errno);
+                    success = false;
+                }
+            }
+        } else {
+            LOG(ERROR) << "Failed to get file stat for " << cur_file_path
+                       << ": " << strerror(errno);
+            success = false;
+        }
+    }
+    return success;
+}
+
+// Archives all files in |input_dir| and writes result into |out_fd|
+// Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive"
+// portion
+size_t cpioFilesInDir(int out_fd, const char* input_dir) {
+    struct dirent* dp;
+    size_t n_error = 0;
+    char read_buf[32 * 1024];
+    DIR* dir_dump = opendir(input_dir);
+    if (!dir_dump) {
+        LOG(ERROR) << "Failed to open directory: " << strerror(errno);
+        n_error++;
+        return n_error;
+    }
+    unique_fd dir_auto_closer(dirfd(dir_dump));
+    while ((dp = readdir(dir_dump))) {
+        if (dp->d_type != DT_REG) {
+            continue;
+        }
+        std::string cur_file_name(dp->d_name);
+        const size_t file_name_len =
+            cur_file_name.size() + 1;  // string.size() does not include the
+                                       // null terminator. The cpio FreeBSD file
+                                       // header expects the null character to
+                                       // be included in the length.
+        struct stat st;
+        ssize_t llen;
+        const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
+        if (stat(cur_file_path.c_str(), &st) != -1) {
+            const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
+            unique_fd file_auto_closer(fd_read);
+            if (fd_read == -1) {
+                LOG(ERROR) << "Failed to read file " << cur_file_path << " "
+                           << strerror(errno);
+                n_error++;
+                continue;
+            }
+            llen = sprintf(
+                read_buf,
+                "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
+                kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid,
+                st.st_gid, static_cast<int>(st.st_nlink),
+                static_cast<int>(st.st_mtime), static_cast<int>(st.st_size),
+                major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
+                minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
+            if (write(out_fd, read_buf, llen) == -1) {
+                LOG(ERROR) << "Error writing cpio header to file "
+                           << cur_file_path << " " << strerror(errno);
+                n_error++;
+                return n_error;
+            }
+            if (write(out_fd, cur_file_name.c_str(), file_name_len) == -1) {
+                LOG(ERROR) << "Error writing filename to file " << cur_file_path
+                           << " " << strerror(errno);
+                n_error++;
+                return n_error;
+            }
+
+            // NUL Pad header up to 4 multiple bytes.
+            llen = (llen + file_name_len) % 4;
+            if (llen != 0) {
+                const uint32_t zero = 0;
+                if (write(out_fd, &zero, 4 - llen) == -1) {
+                    LOG(ERROR) << "Error padding 0s to file " << cur_file_path
+                               << " " << strerror(errno);
+                    n_error++;
+                    return n_error;
+                }
+            }
+
+            // writing content of file
+            llen = st.st_size;
+            while (llen > 0) {
+                ssize_t bytes_read = read(fd_read, read_buf, sizeof(read_buf));
+                if (bytes_read == -1) {
+                    LOG(ERROR) << "Error reading file " << cur_file_path << " "
+                               << strerror(errno);
+                    n_error++;
+                    return n_error;
+                }
+                llen -= bytes_read;
+                if (write(out_fd, read_buf, bytes_read) == -1) {
+                    LOG(ERROR) << "Error writing data to file " << cur_file_path
+                               << " " << strerror(errno);
+                    n_error++;
+                    return n_error;
+                }
+                if (bytes_read ==
+                    0) {  // this should never happen, but just in case
+                          // to unstuck from while loop
+                    LOG(ERROR) << "Unexpected file size for " << cur_file_path
+                               << " " << strerror(errno);
+                    n_error++;
+                    break;
+                }
+            }
+            llen = st.st_size % 4;
+            if (llen != 0) {
+                const uint32_t zero = 0;
+                write(out_fd, &zero, 4 - llen);
+            }
+        } else {
+            LOG(ERROR) << "Failed to get file stat for " << cur_file_path
+                       << ": " << strerror(errno);
+            n_error++;
+        }
+    }
+    memset(read_buf, 0, sizeof(read_buf));
+    if (write(out_fd, read_buf,
+              sprintf(read_buf, "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0) +
+                  4) == -1) {
+        LOG(ERROR) << "Error writing trailing bytes " << strerror(errno);
+        n_error++;
+    }
+    return n_error;
+}
+
+// Helper function to create a non-const char*.
+std::vector<char> makeCharVec(const std::string& str) {
+    std::vector<char> vec(str.size() + 1);
+    vec.assign(str.begin(), str.end());
+    vec.push_back('\0');
+    return vec;
+}
+
 }  // namespace
 
 namespace android {
@@ -350,6 +520,24 @@
                            hidl_status_cb);
 }
 
+Return<void> WifiChip::debug(const hidl_handle& handle,
+                             const hidl_vec<hidl_string>&) {
+    if (handle != nullptr && handle->numFds >= 1) {
+        int fd = handle->data[0];
+        if (!writeRingbufferFilesInternal()) {
+            LOG(ERROR) << "Error writing files to flash";
+        }
+        uint32_t n_error = cpioFilesInDir(fd, kTombstoneFolderPath);
+        if (n_error != 0) {
+            LOG(ERROR) << n_error << " errors occured in cpio function";
+        }
+        fsync(fd);
+    } else {
+        LOG(ERROR) << "File handle error";
+    }
+    return Void();
+}
+
 void WifiChip::invalidateAndRemoveAllIfaces() {
     invalidateAndClearAll(ap_ifaces_);
     invalidateAndClearAll(nan_ifaces_);
@@ -727,6 +915,8 @@
                 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
                 verbose_level),
             max_interval_in_sec, min_data_size_in_bytes);
+    ringbuffer_map_.insert(std::pair<std::string, Ringbuffer>(
+        ring_name, Ringbuffer(kMaxBufferSizeBytes)));
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
@@ -738,6 +928,7 @@
     }
     legacy_hal::wifi_error legacy_status =
         legacy_hal_.lock()->getRingBufferData(getWlan0IfaceName(), ring_name);
+
     return createWifiStatusFromLegacyError(legacy_status);
 }
 
@@ -849,7 +1040,7 @@
 
     android::wp<WifiChip> weak_ptr_this(this);
     const auto& on_ring_buffer_data_callback =
-        [weak_ptr_this](const std::string& /* name */,
+        [weak_ptr_this](const std::string& name,
                         const std::vector<uint8_t>& data,
                         const legacy_hal::wifi_ring_buffer_status& status) {
             const auto shared_ptr_this = weak_ptr_this.promote();
@@ -863,13 +1054,13 @@
                 LOG(ERROR) << "Error converting ring buffer status";
                 return;
             }
-            for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
-                if (!callback->onDebugRingBufferDataAvailable(hidl_status, data)
-                         .isOk()) {
-                    LOG(ERROR)
-                        << "Failed to invoke onDebugRingBufferDataAvailable"
-                        << " callback on: " << toString(callback);
-                }
+            const auto& target = shared_ptr_this->ringbuffer_map_.find(name);
+            if (target != shared_ptr_this->ringbuffer_map_.end()) {
+                Ringbuffer& cur_buffer = target->second;
+                cur_buffer.append(data);
+            } else {
+                LOG(ERROR) << "Ringname " << name << " not found";
+                return;
             }
         };
     legacy_hal::wifi_error legacy_status =
@@ -1080,6 +1271,35 @@
     return {};
 }
 
+bool WifiChip::writeRingbufferFilesInternal() {
+    if (!removeOldFilesInternal()) {
+        LOG(ERROR) << "Error occurred while deleting old tombstone files";
+        return false;
+    }
+    // write ringbuffers to file
+    for (const auto& item : ringbuffer_map_) {
+        const Ringbuffer& cur_buffer = item.second;
+        if (cur_buffer.getData().empty()) {
+            continue;
+        }
+        const std::string file_path_raw =
+            kTombstoneFolderPath + item.first + "XXXXXXXXXX";
+        const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
+        if (dump_fd == -1) {
+            LOG(ERROR) << "create file failed: " << strerror(errno);
+            return false;
+        }
+        unique_fd file_auto_closer(dump_fd);
+        for (const auto& cur_block : cur_buffer.getData()) {
+            if (write(dump_fd, cur_block.data(),
+                      sizeof(cur_block[0]) * cur_block.size()) == -1) {
+                LOG(ERROR) << "Error writing to file " << strerror(errno);
+            }
+        }
+    }
+    return true;
+}
+
 }  // namespace implementation
 }  // namespace V1_2
 }  // namespace wifi
diff --git a/wifi/1.2/default/wifi_chip.h b/wifi/1.2/default/wifi_chip.h
index b5dcc8c..4ffa8da 100644
--- a/wifi/1.2/default/wifi_chip.h
+++ b/wifi/1.2/default/wifi_chip.h
@@ -17,12 +17,14 @@
 #ifndef WIFI_CHIP_H_
 #define WIFI_CHIP_H_
 
+#include <list>
 #include <map>
 
 #include <android-base/macros.h>
 #include <android/hardware/wifi/1.2/IWifiChip.h>
 
 #include "hidl_callback_util.h"
+#include "ringbuffer.h"
 #include "wifi_ap_iface.h"
 #include "wifi_feature_flags.h"
 #include "wifi_legacy_hal.h"
@@ -134,6 +136,8 @@
         selectTxPowerScenario_cb hidl_status_cb) override;
     Return<void> resetTxPowerScenario(
         resetTxPowerScenario_cb hidl_status_cb) override;
+    Return<void> debug(const hidl_handle& handle,
+                       const hidl_vec<hidl_string>& options) override;
 
    private:
     void invalidateAndRemoveAllIfaces();
@@ -204,6 +208,7 @@
     bool canCurrentModeSupportIfaceOfType(IfaceType type);
     bool isValidModeId(ChipModeId mode_id);
     std::string allocateApOrStaIfaceName();
+    bool writeRingbufferFilesInternal();
 
     ChipId chip_id_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
@@ -214,6 +219,7 @@
     std::vector<sp<WifiP2pIface>> p2p_ifaces_;
     std::vector<sp<WifiStaIface>> sta_ifaces_;
     std::vector<sp<WifiRttController>> rtt_controllers_;
+    std::map<std::string, Ringbuffer> ringbuffer_map_;
     bool is_valid_;
     // Members pertaining to chip configuration.
     uint32_t current_mode_id_;