Merge changes I80d7e331,I32178204,I1930fadd into sc-dev

* changes:
  Remove an obsolete CarEvsService test case
  Fix CarEvsService JNI method
  Stop listening to CarEvsService state transitions
diff --git a/car_product/build/car_base.mk b/car_product/build/car_base.mk
index 2f9b344..1deba89 100644
--- a/car_product/build/car_base.mk
+++ b/car_product/build/car_base.mk
@@ -66,7 +66,7 @@
 include packages/services/Car/cpp/evs/manager/evsmanager.mk
 
 # Automotive Telemetry services
-include packages/services/Car/cpp/telemetry/products/telemetry.mk
+include packages/services/Car/cpp/telemetry/cartelemetryd/products/telemetry.mk
 
 # EVS manager overrides cameraserver on automotive implementations so
 # we need to configure Camera API to not connect to it
@@ -82,6 +82,10 @@
 include packages/services/Car/cpp/evs/apps/sepolicy/evsapp.mk
 include packages/services/Car/cpp/evs/sampleDriver/sepolicy/evsdriver.mk
 endif
+ifeq ($(ENABLE_CAREVSSERVICE_SAMPLE), true)
+PRODUCT_PACKAGES += CarEvsCameraPreviewApp \
+                    CarSystemUIEvsRRO
+endif
 ifeq ($(ENABLE_REAR_VIEW_CAMERA_SAMPLE), true)
 PRODUCT_PACKAGES += SampleRearViewCamera
 PRODUCT_PACKAGE_OVERLAYS += packages/services/Car/tests/SampleRearViewCamera/overlay
diff --git a/car_product/rro/CarSystemUIEvsRRO/Android.bp b/car_product/rro/CarSystemUIEvsRRO/Android.bp
new file mode 100644
index 0000000..ebb09ef
--- /dev/null
+++ b/car_product/rro/CarSystemUIEvsRRO/Android.bp
@@ -0,0 +1,25 @@
+// Copyright (C) 2021 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+android_app {
+    name: "CarSystemUIEvsRRO",
+    resource_dirs: ["res"],
+    platform_apis: true,
+    aaptflags: [
+        "--no-resource-deduping",
+        "--no-resource-removal"
+    ],
+}
diff --git a/car_product/rro/CarSystemUIEvsRRO/AndroidManifest.xml b/car_product/rro/CarSystemUIEvsRRO/AndroidManifest.xml
new file mode 100644
index 0000000..f1dc7b8
--- /dev/null
+++ b/car_product/rro/CarSystemUIEvsRRO/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+          package="com.android.systemui.car.evs.rro">
+    <application android:hasCode="false"/>
+    <overlay android:targetName="CarSystemUI"
+             android:targetPackage="com.android.systemui"
+             android:resourcesMap="@xml/overlays"
+             android:isStatic="true" />
+</manifest>
diff --git a/car_product/rro/CarSystemUIEvsRRO/res/values/config.xml b/car_product/rro/CarSystemUIEvsRRO/res/values/config.xml
new file mode 100644
index 0000000..4fab05c
--- /dev/null
+++ b/car_product/rro/CarSystemUIEvsRRO/res/values/config.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+<resources>
+    <string name="config_rearViewCameraActivity" translatable="false">
+        com.google.android.car.evs/com.google.android.car.evs.CarEvsCameraPreviewActivity
+    </string>
+</resources>
diff --git a/car_product/rro/CarSystemUIEvsRRO/res/xml/overlays.xml b/car_product/rro/CarSystemUIEvsRRO/res/xml/overlays.xml
new file mode 100644
index 0000000..36785dc
--- /dev/null
+++ b/car_product/rro/CarSystemUIEvsRRO/res/xml/overlays.xml
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright (C) 2021 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.
+  -->
+
+<overlay>
+    <item target="string/config_rearViewCameraActivity"
+          value="@string/config_rearViewCameraActivity"/>
+</overlay>
diff --git a/cpp/evs/apps/default/EvsStateControl.cpp b/cpp/evs/apps/default/EvsStateControl.cpp
index 6359c81..5552deb 100644
--- a/cpp/evs/apps/default/EvsStateControl.cpp
+++ b/cpp/evs/apps/default/EvsStateControl.cpp
@@ -188,6 +188,7 @@
 
             if (tgtBuffer.memHandle == nullptr) {
                 LOG(ERROR) << "Didn't get requested output buffer -- skipping this frame.";
+                run = false;
             } else {
                 // Generate our output image
                 if (!mCurrentRenderer->drawFrame(convertBufferDesc(tgtBuffer))) {
diff --git a/cpp/evs/manager/1.1/Enumerator.cpp b/cpp/evs/manager/1.1/Enumerator.cpp
index 5ad3471..d6f532d 100644
--- a/cpp/evs/manager/1.1/Enumerator.cpp
+++ b/cpp/evs/manager/1.1/Enumerator.cpp
@@ -49,6 +49,9 @@
     const int kOptionDumpCameraArgsStartIndex = 4;
 
     const std::regex kEmulatedCameraNamePattern("emulated/[0-9]+", std::regex_constants::icase);
+
+    // Display ID 255 is reserved for the special purpose.
+    constexpr int kExclusiveMainDisplayId = 255;
 }
 
 namespace android {
@@ -94,6 +97,14 @@
         );
     }
 
+    auto it = std::find(mDisplayPorts.begin(), mDisplayPorts.end(), kExclusiveMainDisplayId);
+    if (it != mDisplayPorts.end()) {
+        LOG(WARNING) << kExclusiveMainDisplayId << " is reserved for the special purpose "
+                     << "so will not be available for EVS service.";
+        mDisplayPorts.erase(it);
+    }
+    mDisplayOwnedExclusively = false;
+
     // Starts the statistics collection
     mMonitorEnabled = false;
     mClientsMonitor = new StatsCollector();
@@ -462,6 +473,11 @@
         return nullptr;
     }
 
+    if (mDisplayOwnedExclusively) {
+        LOG(ERROR) << "Display is owned exclusively by another client.";
+        return nullptr;
+    }
+
     // We simply keep track of the most recently opened display instance.
     // In the underlying layers we expect that a new open will cause the previous
     // object to be destroyed.  This avoids any race conditions associated with
@@ -500,6 +516,7 @@
         sp<HalDisplay> halDisplay = reinterpret_cast<HalDisplay *>(pActiveDisplay.get());
         mHwEnumerator->closeDisplay(halDisplay->getHwDisplay());
         mActiveDisplay = nullptr;
+        mDisplayOwnedExclusively = false;
     }
 
     return Void();
@@ -532,7 +549,16 @@
         return nullptr;
     }
 
-    if (std::find(mDisplayPorts.begin(), mDisplayPorts.end(), id) == mDisplayPorts.end()) {
+    if (mDisplayOwnedExclusively) {
+        LOG(ERROR) << "Display is owned exclusively by another client.";
+        return nullptr;
+    }
+
+    if (id == kExclusiveMainDisplayId) {
+        // The client requests to open the primary display exclusively.
+        id = mInternalDisplayPort;
+        mDisplayOwnedExclusively = true;
+    } else if (std::find(mDisplayPorts.begin(), mDisplayPorts.end(), id) == mDisplayPorts.end()) {
         LOG(ERROR) << "No display is available on the port " << static_cast<int32_t>(id);
         return nullptr;
     }
diff --git a/cpp/evs/manager/1.1/Enumerator.h b/cpp/evs/manager/1.1/Enumerator.h
index 9e27cd3..468db0c 100644
--- a/cpp/evs/manager/1.1/Enumerator.h
+++ b/cpp/evs/manager/1.1/Enumerator.h
@@ -110,6 +110,9 @@
     // Boolean flag to tell whether the camera usages are being monitored or not
     bool                              mMonitorEnabled;
 
+    // Boolean flag to tell whether EvsDisplay is owned exclusively or not
+    bool                              mDisplayOwnedExclusively;
+
     // LSHAL dump
     void cmdDump(int fd, const hidl_vec<hidl_string>& options);
     void cmdHelp(int fd);
diff --git a/cpp/evs/manager/1.1/HalCamera.cpp b/cpp/evs/manager/1.1/HalCamera.cpp
index dcd3496..c7018bf 100644
--- a/cpp/evs/manager/1.1/HalCamera.cpp
+++ b/cpp/evs/manager/1.1/HalCamera.cpp
@@ -98,7 +98,8 @@
     unsigned clientCount = mClients.size();
     mClients.remove(virtualCamera);
     if (clientCount != mClients.size() + 1) {
-        LOG(ERROR) << "Couldn't find camera in our client list to remove it";
+        LOG(ERROR) << "Couldn't find camera in our client list to remove it; "
+                   << "this client may be removed already.";
     }
 
     // Recompute the number of buffers required with the target camera removed from the list
@@ -365,10 +366,14 @@
 
                 // Reports a skipped frame
                 mUsageStats->framesSkippedToSync();
-            } else if (vCam != nullptr && vCam->deliverFrame(buffer[0])) {
-                // Forward a frame and move a timeline.
-                LOG(DEBUG) << getId() << " forwarded the buffer #" << buffer[0].bufferId;
-                ++frameDeliveriesV1;
+            } else if (vCam != nullptr) {
+                if (!vCam->deliverFrame(buffer[0])) {
+                    LOG(WARNING) << getId() << " failed to forward the buffer to " << vCam.get();
+                } else {
+                    LOG(ERROR) << getId() << " forwarded the buffer #" << buffer[0].bufferId
+                               << " to " << vCam.get() << " from " << this;
+                    ++frameDeliveriesV1;
+                }
             }
         }
     }
diff --git a/cpp/evs/manager/1.1/VirtualCamera.cpp b/cpp/evs/manager/1.1/VirtualCamera.cpp
index 63c0a31..a7e6329 100644
--- a/cpp/evs/manager/1.1/VirtualCamera.cpp
+++ b/cpp/evs/manager/1.1/VirtualCamera.cpp
@@ -59,6 +59,10 @@
         // Tell the frame delivery pipeline we don't want any more frames
         mStreamState = STOPPING;
 
+        // Awakes the capture thread; this thread will terminate.
+        mFramesReadySignal.notify_all();
+
+        // Returns buffers held by this client
         for (auto&& [key, hwCamera] : mHalCamera) {
             auto pHwCamera = hwCamera.promote();
             if (pHwCamera == nullptr) {
@@ -131,6 +135,13 @@
             }
         }
 
+        // Marks that a new frame has arrived though it was not accepted
+        {
+            std::lock_guard<std::mutex> lock(mFrameDeliveryMutex);
+            mSourceCameras.erase(bufDesc.deviceId);
+            mFramesReadySignal.notify_all();
+        }
+
         return false;
     } else {
         // Keep a record of this frame so we can clean up if we have to in case of client death
@@ -364,7 +375,12 @@
                 if (!mFramesReadySignal.wait_for(lock,
                                                  kFrameTimeout,
                                                  [this]() REQUIRES(mFrameDeliveryMutex) {
-                                                     return mSourceCameras.empty();
+                                                     // Stops waiting if
+                                                     // 1) we've requested to stop capturing
+                                                     //    new frames
+                                                     // 2) or, we've got all frames
+                                                     return mStreamState != RUNNING ||
+                                                            mSourceCameras.empty();
                                                  })) {
                     // This happens when either a new frame does not arrive
                     // before a timer expires or we're requested to stop
@@ -396,8 +412,12 @@
                             LOG(WARNING) << "Failed to forward frames";
                         }
                     }
+                } else if (mStreamState != RUNNING) {
+                    LOG(DEBUG) << "Requested to stop capturing frames";
                 }
             }
+
+            LOG(DEBUG) << "Exiting a capture thread";
         });
     }
 
@@ -455,7 +475,10 @@
         // Tell the frame delivery pipeline we don't want any more frames
         mStreamState = STOPPING;
 
-        // Deliver an empty frame to close out the frame stream
+        // Awake the capture thread; this thread will terminate.
+        mFramesReadySignal.notify_all();
+
+        // Deliver the stream-ending notification
         if (mStream_1_1 != nullptr) {
             // v1.1 client waits for a stream stopped event
             EvsEventDesc event;
diff --git a/cpp/telemetry/ARCHITECTURE.md b/cpp/telemetry/cartelemetryd/ARCHITECTURE.md
similarity index 100%
rename from cpp/telemetry/ARCHITECTURE.md
rename to cpp/telemetry/cartelemetryd/ARCHITECTURE.md
diff --git a/cpp/telemetry/Android.bp b/cpp/telemetry/cartelemetryd/Android.bp
similarity index 100%
rename from cpp/telemetry/Android.bp
rename to cpp/telemetry/cartelemetryd/Android.bp
diff --git a/cpp/telemetry/README.md b/cpp/telemetry/cartelemetryd/README.md
similarity index 100%
rename from cpp/telemetry/README.md
rename to cpp/telemetry/cartelemetryd/README.md
diff --git a/cpp/telemetry/aidl/Android.bp b/cpp/telemetry/cartelemetryd/aidl/Android.bp
similarity index 100%
rename from cpp/telemetry/aidl/Android.bp
rename to cpp/telemetry/cartelemetryd/aidl/Android.bp
diff --git a/cpp/telemetry/aidl/android/automotive/telemetry/internal/CarDataInternal.aidl b/cpp/telemetry/cartelemetryd/aidl/android/automotive/telemetry/internal/CarDataInternal.aidl
similarity index 100%
rename from cpp/telemetry/aidl/android/automotive/telemetry/internal/CarDataInternal.aidl
rename to cpp/telemetry/cartelemetryd/aidl/android/automotive/telemetry/internal/CarDataInternal.aidl
diff --git a/cpp/telemetry/aidl/android/automotive/telemetry/internal/ICarDataListener.aidl b/cpp/telemetry/cartelemetryd/aidl/android/automotive/telemetry/internal/ICarDataListener.aidl
similarity index 100%
rename from cpp/telemetry/aidl/android/automotive/telemetry/internal/ICarDataListener.aidl
rename to cpp/telemetry/cartelemetryd/aidl/android/automotive/telemetry/internal/ICarDataListener.aidl
diff --git a/cpp/telemetry/aidl/android/automotive/telemetry/internal/ICarTelemetryInternal.aidl b/cpp/telemetry/cartelemetryd/aidl/android/automotive/telemetry/internal/ICarTelemetryInternal.aidl
similarity index 100%
rename from cpp/telemetry/aidl/android/automotive/telemetry/internal/ICarTelemetryInternal.aidl
rename to cpp/telemetry/cartelemetryd/aidl/android/automotive/telemetry/internal/ICarTelemetryInternal.aidl
diff --git a/cpp/telemetry/android.automotive.telemetryd@1.0.rc b/cpp/telemetry/cartelemetryd/android.automotive.telemetryd@1.0.rc
similarity index 100%
rename from cpp/telemetry/android.automotive.telemetryd@1.0.rc
rename to cpp/telemetry/cartelemetryd/android.automotive.telemetryd@1.0.rc
diff --git a/cpp/telemetry/android.automotive.telemetryd@1.0.xml b/cpp/telemetry/cartelemetryd/android.automotive.telemetryd@1.0.xml
similarity index 100%
rename from cpp/telemetry/android.automotive.telemetryd@1.0.xml
rename to cpp/telemetry/cartelemetryd/android.automotive.telemetryd@1.0.xml
diff --git a/cpp/telemetry/products/telemetry.mk b/cpp/telemetry/cartelemetryd/products/telemetry.mk
similarity index 92%
rename from cpp/telemetry/products/telemetry.mk
rename to cpp/telemetry/cartelemetryd/products/telemetry.mk
index 634c9a9..86161bd 100644
--- a/cpp/telemetry/products/telemetry.mk
+++ b/cpp/telemetry/cartelemetryd/products/telemetry.mk
@@ -16,7 +16,7 @@
 PRODUCT_PACKAGES += android.automotive.telemetryd@1.0
 
 # Selinux public policies for cartelemetry
-PRODUCT_PUBLIC_SEPOLICY_DIRS += packages/services/Car/cpp/telemetry/sepolicy/public
+PRODUCT_PUBLIC_SEPOLICY_DIRS += packages/services/Car/cpp/telemetry/cartelemetryd/sepolicy/public
 
 # Selinux private policies for cartelemetry
-PRODUCT_PRIVATE_SEPOLICY_DIRS += packages/services/Car/cpp/telemetry/sepolicy/private
+PRODUCT_PRIVATE_SEPOLICY_DIRS += packages/services/Car/cpp/telemetry/cartelemetryd/sepolicy/private
diff --git a/cpp/telemetry/sampleclient/Android.bp b/cpp/telemetry/cartelemetryd/sampleclient/Android.bp
similarity index 100%
rename from cpp/telemetry/sampleclient/Android.bp
rename to cpp/telemetry/cartelemetryd/sampleclient/Android.bp
diff --git a/cpp/telemetry/sampleclient/README.md b/cpp/telemetry/cartelemetryd/sampleclient/README.md
similarity index 94%
rename from cpp/telemetry/sampleclient/README.md
rename to cpp/telemetry/cartelemetryd/sampleclient/README.md
index 5b97f00..ae86300 100644
--- a/cpp/telemetry/sampleclient/README.md
+++ b/cpp/telemetry/cartelemetryd/sampleclient/README.md
@@ -23,7 +23,7 @@
 
 To include it in the final image, add
 `PRODUCT_PACKAGES += android.automotive.telemetryd-sampleclient` to
-`//packages/services/Car/cpp/telemetry/products/telemetry.mk` (or other suitable mk file).
+`//packages/services/Car/cpp/telemetry/cartelemetryd/products/telemetry.mk` (or other suitable mk file).
 
 ```
 # this goes to products/telemetry.mk
diff --git a/cpp/telemetry/sampleclient/main.cpp b/cpp/telemetry/cartelemetryd/sampleclient/main.cpp
similarity index 100%
rename from cpp/telemetry/sampleclient/main.cpp
rename to cpp/telemetry/cartelemetryd/sampleclient/main.cpp
diff --git a/cpp/telemetry/sampleinternalclient/Android.bp b/cpp/telemetry/cartelemetryd/sampleinternalclient/Android.bp
similarity index 100%
rename from cpp/telemetry/sampleinternalclient/Android.bp
rename to cpp/telemetry/cartelemetryd/sampleinternalclient/Android.bp
diff --git a/cpp/telemetry/sampleinternalclient/main.cpp b/cpp/telemetry/cartelemetryd/sampleinternalclient/main.cpp
similarity index 100%
rename from cpp/telemetry/sampleinternalclient/main.cpp
rename to cpp/telemetry/cartelemetryd/sampleinternalclient/main.cpp
diff --git a/cpp/telemetry/sepolicy/private/cartelemetryd.te b/cpp/telemetry/cartelemetryd/sepolicy/private/cartelemetryd.te
similarity index 100%
rename from cpp/telemetry/sepolicy/private/cartelemetryd.te
rename to cpp/telemetry/cartelemetryd/sepolicy/private/cartelemetryd.te
diff --git a/cpp/telemetry/sepolicy/private/file_contexts b/cpp/telemetry/cartelemetryd/sepolicy/private/file_contexts
similarity index 100%
rename from cpp/telemetry/sepolicy/private/file_contexts
rename to cpp/telemetry/cartelemetryd/sepolicy/private/file_contexts
diff --git a/cpp/telemetry/sepolicy/private/service_contexts b/cpp/telemetry/cartelemetryd/sepolicy/private/service_contexts
similarity index 100%
rename from cpp/telemetry/sepolicy/private/service_contexts
rename to cpp/telemetry/cartelemetryd/sepolicy/private/service_contexts
diff --git a/cpp/telemetry/sepolicy/public/cartelemetryd.te b/cpp/telemetry/cartelemetryd/sepolicy/public/cartelemetryd.te
similarity index 100%
rename from cpp/telemetry/sepolicy/public/cartelemetryd.te
rename to cpp/telemetry/cartelemetryd/sepolicy/public/cartelemetryd.te
diff --git a/cpp/telemetry/sepolicy/public/service.te b/cpp/telemetry/cartelemetryd/sepolicy/public/service.te
similarity index 100%
rename from cpp/telemetry/sepolicy/public/service.te
rename to cpp/telemetry/cartelemetryd/sepolicy/public/service.te
diff --git a/cpp/telemetry/src/BufferedCarData.h b/cpp/telemetry/cartelemetryd/src/BufferedCarData.h
similarity index 89%
rename from cpp/telemetry/src/BufferedCarData.h
rename to cpp/telemetry/cartelemetryd/src/BufferedCarData.h
index 0c6ff4d..1a24f78 100644
--- a/cpp/telemetry/src/BufferedCarData.h
+++ b/cpp/telemetry/cartelemetryd/src/BufferedCarData.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef CPP_TELEMETRY_SRC_BUFFEREDCARDATA_H_
-#define CPP_TELEMETRY_SRC_BUFFEREDCARDATA_H_
+#ifndef CPP_TELEMETRY_CARTELEMETRYD_SRC_BUFFEREDCARDATA_H_
+#define CPP_TELEMETRY_CARTELEMETRYD_SRC_BUFFEREDCARDATA_H_
 
 #include <stdint.h>
 
@@ -52,4 +52,4 @@
 }  // namespace automotive
 }  // namespace android
 
-#endif  // CPP_TELEMETRY_SRC_BUFFEREDCARDATA_H_
+#endif  // CPP_TELEMETRY_CARTELEMETRYD_SRC_BUFFEREDCARDATA_H_
diff --git a/cpp/telemetry/src/CarTelemetryImpl.cpp b/cpp/telemetry/cartelemetryd/src/CarTelemetryImpl.cpp
similarity index 100%
rename from cpp/telemetry/src/CarTelemetryImpl.cpp
rename to cpp/telemetry/cartelemetryd/src/CarTelemetryImpl.cpp
diff --git a/cpp/telemetry/src/CarTelemetryImpl.h b/cpp/telemetry/cartelemetryd/src/CarTelemetryImpl.h
similarity index 88%
rename from cpp/telemetry/src/CarTelemetryImpl.h
rename to cpp/telemetry/cartelemetryd/src/CarTelemetryImpl.h
index e10dd98..792487d 100644
--- a/cpp/telemetry/src/CarTelemetryImpl.h
+++ b/cpp/telemetry/cartelemetryd/src/CarTelemetryImpl.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef CPP_TELEMETRY_SRC_CARTELEMETRYIMPL_H_
-#define CPP_TELEMETRY_SRC_CARTELEMETRYIMPL_H_
+#ifndef CPP_TELEMETRY_CARTELEMETRYD_SRC_CARTELEMETRYIMPL_H_
+#define CPP_TELEMETRY_CARTELEMETRYD_SRC_CARTELEMETRYIMPL_H_
 
 #include "TelemetryServer.h"
 
@@ -48,4 +48,4 @@
 }  // namespace automotive
 }  // namespace android
 
-#endif  // CPP_TELEMETRY_SRC_CARTELEMETRYIMPL_H_
+#endif  // CPP_TELEMETRY_CARTELEMETRYD_SRC_CARTELEMETRYIMPL_H_
diff --git a/cpp/telemetry/src/CarTelemetryInternalImpl.cpp b/cpp/telemetry/cartelemetryd/src/CarTelemetryInternalImpl.cpp
similarity index 100%
rename from cpp/telemetry/src/CarTelemetryInternalImpl.cpp
rename to cpp/telemetry/cartelemetryd/src/CarTelemetryInternalImpl.cpp
diff --git a/cpp/telemetry/src/CarTelemetryInternalImpl.h b/cpp/telemetry/cartelemetryd/src/CarTelemetryInternalImpl.h
similarity index 90%
rename from cpp/telemetry/src/CarTelemetryInternalImpl.h
rename to cpp/telemetry/cartelemetryd/src/CarTelemetryInternalImpl.h
index 599d580..f9710b4 100644
--- a/cpp/telemetry/src/CarTelemetryInternalImpl.h
+++ b/cpp/telemetry/cartelemetryd/src/CarTelemetryInternalImpl.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef CPP_TELEMETRY_SRC_CARTELEMETRYINTERNALIMPL_H_
-#define CPP_TELEMETRY_SRC_CARTELEMETRYINTERNALIMPL_H_
+#ifndef CPP_TELEMETRY_CARTELEMETRYD_SRC_CARTELEMETRYINTERNALIMPL_H_
+#define CPP_TELEMETRY_CARTELEMETRYD_SRC_CARTELEMETRYINTERNALIMPL_H_
 
 #include "TelemetryServer.h"
 
@@ -61,4 +61,4 @@
 }  // namespace automotive
 }  // namespace android
 
-#endif  // CPP_TELEMETRY_SRC_CARTELEMETRYINTERNALIMPL_H_
+#endif  // CPP_TELEMETRY_CARTELEMETRYD_SRC_CARTELEMETRYINTERNALIMPL_H_
diff --git a/cpp/telemetry/src/LooperWrapper.cpp b/cpp/telemetry/cartelemetryd/src/LooperWrapper.cpp
similarity index 100%
rename from cpp/telemetry/src/LooperWrapper.cpp
rename to cpp/telemetry/cartelemetryd/src/LooperWrapper.cpp
diff --git a/cpp/telemetry/src/LooperWrapper.h b/cpp/telemetry/cartelemetryd/src/LooperWrapper.h
similarity index 82%
rename from cpp/telemetry/src/LooperWrapper.h
rename to cpp/telemetry/cartelemetryd/src/LooperWrapper.h
index 171c57f..1c0366d 100644
--- a/cpp/telemetry/src/LooperWrapper.h
+++ b/cpp/telemetry/cartelemetryd/src/LooperWrapper.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef CPP_TELEMETRY_SRC_LOOPERWRAPPER_H_
-#define CPP_TELEMETRY_SRC_LOOPERWRAPPER_H_
+#ifndef CPP_TELEMETRY_CARTELEMETRYD_SRC_LOOPERWRAPPER_H_
+#define CPP_TELEMETRY_CARTELEMETRYD_SRC_LOOPERWRAPPER_H_
 
 #include <utils/Looper.h>
 
@@ -28,8 +28,8 @@
 // Refer to utils/Looper.h for the class and methods descriptions.
 class LooperWrapper {
 public:
-    LooperWrapper(android::sp<Looper> looper) : mLooper(looper){};
-    virtual ~LooperWrapper(){};
+    explicit LooperWrapper(android::sp<Looper> looper) : mLooper(looper) {}
+    virtual ~LooperWrapper() {}
 
     virtual int pollAll(int timeoutMillis);
     virtual void sendMessageDelayed(nsecs_t uptime, const android::sp<MessageHandler>& handler,
@@ -44,4 +44,4 @@
 }  // namespace automotive
 }  // namespace android
 
-#endif  // CPP_TELEMETRY_SRC_LOOPERWRAPPER_H_
+#endif  // CPP_TELEMETRY_CARTELEMETRYD_SRC_LOOPERWRAPPER_H_
diff --git a/cpp/telemetry/src/RingBuffer.cpp b/cpp/telemetry/cartelemetryd/src/RingBuffer.cpp
similarity index 100%
rename from cpp/telemetry/src/RingBuffer.cpp
rename to cpp/telemetry/cartelemetryd/src/RingBuffer.cpp
diff --git a/cpp/telemetry/src/RingBuffer.h b/cpp/telemetry/cartelemetryd/src/RingBuffer.h
similarity index 92%
rename from cpp/telemetry/src/RingBuffer.h
rename to cpp/telemetry/cartelemetryd/src/RingBuffer.h
index 3247528..84f0ed5 100644
--- a/cpp/telemetry/src/RingBuffer.h
+++ b/cpp/telemetry/cartelemetryd/src/RingBuffer.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef CPP_TELEMETRY_SRC_RINGBUFFER_H_
-#define CPP_TELEMETRY_SRC_RINGBUFFER_H_
+#ifndef CPP_TELEMETRY_CARTELEMETRYD_SRC_RINGBUFFER_H_
+#define CPP_TELEMETRY_CARTELEMETRYD_SRC_RINGBUFFER_H_
 
 #include "BufferedCarData.h"
 
@@ -66,4 +66,4 @@
 }  // namespace automotive
 }  // namespace android
 
-#endif  // CPP_TELEMETRY_SRC_RINGBUFFER_H_
+#endif  // CPP_TELEMETRY_CARTELEMETRYD_SRC_RINGBUFFER_H_
diff --git a/cpp/telemetry/src/TelemetryServer.cpp b/cpp/telemetry/cartelemetryd/src/TelemetryServer.cpp
similarity index 100%
rename from cpp/telemetry/src/TelemetryServer.cpp
rename to cpp/telemetry/cartelemetryd/src/TelemetryServer.cpp
diff --git a/cpp/telemetry/src/TelemetryServer.h b/cpp/telemetry/cartelemetryd/src/TelemetryServer.h
similarity index 95%
rename from cpp/telemetry/src/TelemetryServer.h
rename to cpp/telemetry/cartelemetryd/src/TelemetryServer.h
index 20c3839..61263db 100644
--- a/cpp/telemetry/src/TelemetryServer.h
+++ b/cpp/telemetry/cartelemetryd/src/TelemetryServer.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef CPP_TELEMETRY_SRC_TELEMETRYSERVER_H_
-#define CPP_TELEMETRY_SRC_TELEMETRYSERVER_H_
+#ifndef CPP_TELEMETRY_CARTELEMETRYD_SRC_TELEMETRYSERVER_H_
+#define CPP_TELEMETRY_CARTELEMETRYD_SRC_TELEMETRYSERVER_H_
 
 #include "LooperWrapper.h"
 #include "RingBuffer.h"
@@ -107,4 +107,4 @@
 }  // namespace automotive
 }  // namespace android
 
-#endif  // CPP_TELEMETRY_SRC_TELEMETRYSERVER_H_
+#endif  // CPP_TELEMETRY_CARTELEMETRYD_SRC_TELEMETRYSERVER_H_
diff --git a/cpp/telemetry/src/main.cpp b/cpp/telemetry/cartelemetryd/src/main.cpp
similarity index 100%
rename from cpp/telemetry/src/main.cpp
rename to cpp/telemetry/cartelemetryd/src/main.cpp
diff --git a/cpp/telemetry/tests/FakeLooperWrapper.h b/cpp/telemetry/cartelemetryd/tests/FakeLooperWrapper.h
similarity index 92%
rename from cpp/telemetry/tests/FakeLooperWrapper.h
rename to cpp/telemetry/cartelemetryd/tests/FakeLooperWrapper.h
index 1914ee5..b24b709 100644
--- a/cpp/telemetry/tests/FakeLooperWrapper.h
+++ b/cpp/telemetry/cartelemetryd/tests/FakeLooperWrapper.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef CPP_TELEMETRY_SRC_TESTS_FAKELOOPERWRAPPER_H_
-#define CPP_TELEMETRY_SRC_TESTS_FAKELOOPERWRAPPER_H_
+#ifndef CPP_TELEMETRY_CARTELEMETRYD_TESTS_FAKELOOPERWRAPPER_H_
+#define CPP_TELEMETRY_CARTELEMETRYD_TESTS_FAKELOOPERWRAPPER_H_
 
 #include "LooperWrapper.h"
 
@@ -35,7 +35,7 @@
 public:
     static inline constexpr int kNoScheduledMessage = -1;
 
-    FakeLooperWrapper() : LooperWrapper(nullptr){};
+    FakeLooperWrapper() : LooperWrapper(nullptr) {}
 
     int pollAll(int timeoutMillis) override { return 0; }
 
@@ -101,4 +101,4 @@
 }  // namespace automotive
 }  // namespace android
 
-#endif  // CPP_TELEMETRY_SRC_TESTS_FAKELOOPERWRAPPER_H_
+#endif  // CPP_TELEMETRY_CARTELEMETRYD_TESTS_FAKELOOPERWRAPPER_H_
diff --git a/cpp/telemetry/tests/TelemetryServerTest.cpp b/cpp/telemetry/cartelemetryd/tests/TelemetryServerTest.cpp
similarity index 100%
rename from cpp/telemetry/tests/TelemetryServerTest.cpp
rename to cpp/telemetry/cartelemetryd/tests/TelemetryServerTest.cpp
diff --git a/cpp/telemetry/script_executor/Android.bp b/cpp/telemetry/script_executor/Android.bp
new file mode 100644
index 0000000..734d4dd
--- /dev/null
+++ b/cpp/telemetry/script_executor/Android.bp
@@ -0,0 +1,28 @@
+// Copyright (C) 2021 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+cc_library {
+   name: "script_executor",
+   srcs: [
+       "src/LuaEngine.cpp",
+   ],
+   static_libs: [
+       "liblua",
+   ],
+}
+
diff --git a/cpp/telemetry/script_executor/src/LuaEngine.cpp b/cpp/telemetry/script_executor/src/LuaEngine.cpp
new file mode 100644
index 0000000..a8cace3
--- /dev/null
+++ b/cpp/telemetry/script_executor/src/LuaEngine.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2021, 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 "LuaEngine.h"
+
+#include <utility>
+
+extern "C" {
+#include "lauxlib.h"
+#include "lualib.h"
+}
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+namespace script_executor {
+
+LuaEngine::LuaEngine(std::unique_ptr<ScriptExecutorListener> listener) :
+      mListener(std::move(listener)) {
+    mLuaState = luaL_newstate();
+    luaL_openlibs(mLuaState);
+}
+
+LuaEngine::~LuaEngine() {
+    lua_close(mLuaState);
+}
+
+}  // namespace script_executor
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
diff --git a/cpp/telemetry/script_executor/src/LuaEngine.h b/cpp/telemetry/script_executor/src/LuaEngine.h
new file mode 100644
index 0000000..086dbfe
--- /dev/null
+++ b/cpp/telemetry/script_executor/src/LuaEngine.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2021, 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 CPP_TELEMETRY_SCRIPT_EXECUTOR_SRC_LUAENGINE_H_
+#define CPP_TELEMETRY_SCRIPT_EXECUTOR_SRC_LUAENGINE_H_
+
+#include "ScriptExecutorListener.h"
+
+#include <memory>
+
+extern "C" {
+#include "lua.h"
+}
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+namespace script_executor {
+
+// Encapsulates Lua script execution environment.
+class LuaEngine {
+public:
+    explicit LuaEngine(std::unique_ptr<ScriptExecutorListener> listener);
+
+    virtual ~LuaEngine();
+
+private:
+    lua_State* mLuaState;  // owned
+
+    std::unique_ptr<ScriptExecutorListener> mListener;
+};
+
+}  // namespace script_executor
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
+
+#endif  // CPP_TELEMETRY_SCRIPT_EXECUTOR_SRC_LUAENGINE_H_
diff --git a/cpp/telemetry/script_executor/src/ScriptExecutorListener.cpp b/cpp/telemetry/script_executor/src/ScriptExecutorListener.cpp
new file mode 100644
index 0000000..8a46253
--- /dev/null
+++ b/cpp/telemetry/script_executor/src/ScriptExecutorListener.cpp
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2021, 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 "ScriptExecutorListener.h"
+
+#include <android-base/logging.h>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+namespace script_executor {
+
+void ScriptExecutorListener::onError(const int errorType, const std::string& message,
+                                     const std::string& stackTrace) {
+    LOG(INFO) << "errorType: " << errorType << ", message: " << message
+              << ", stackTrace: " << stackTrace;
+}
+
+}  // namespace script_executor
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
diff --git a/cpp/telemetry/script_executor/src/ScriptExecutorListener.h b/cpp/telemetry/script_executor/src/ScriptExecutorListener.h
new file mode 100644
index 0000000..d9d8213
--- /dev/null
+++ b/cpp/telemetry/script_executor/src/ScriptExecutorListener.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2021, 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 CPP_TELEMETRY_SCRIPT_EXECUTOR_SRC_SCRIPTEXECUTORLISTENER_H_
+#define CPP_TELEMETRY_SCRIPT_EXECUTOR_SRC_SCRIPTEXECUTORLISTENER_H_
+
+#include <string>
+
+namespace android {
+namespace automotive {
+namespace telemetry {
+namespace script_executor {
+
+//  Wrapper class for IScriptExecutorListener.aidl.
+class ScriptExecutorListener {
+public:
+    void onScriptFinished() {}
+
+    void onSuccess() {}
+
+    void onError(const int errorType, const std::string& message, const std::string& stackTrace);
+};
+
+}  // namespace script_executor
+}  // namespace telemetry
+}  // namespace automotive
+}  // namespace android
+
+#endif  // CPP_TELEMETRY_SCRIPT_EXECUTOR_SRC_SCRIPTEXECUTORLISTENER_H_
diff --git a/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.aidl b/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.aidl
index ef68dbc..c0cfd23 100644
--- a/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.aidl
+++ b/cpp/watchdog/aidl/android/automotive/watchdog/internal/ICarWatchdogServiceForSystem.aidl
@@ -62,4 +62,11 @@
    *                                    recent collection.
    */
   oneway void latestIoOveruseStats(in List<PackageIoOveruseStats> packageIoOveruseStats);
+
+  /**
+   * Resets resource overuse stats on the watchdog server side.
+   *
+   * @param packageNames       Package names for which to reset the stats.
+   */
+  oneway void resetResourceOveruseStats(in @utf8InCpp List<String> packageNames);
 }
diff --git a/cpp/watchdog/server/src/IoOveruseMonitor.cpp b/cpp/watchdog/server/src/IoOveruseMonitor.cpp
index c724d57..ddc606b 100644
--- a/cpp/watchdog/server/src/IoOveruseMonitor.cpp
+++ b/cpp/watchdog/server/src/IoOveruseMonitor.cpp
@@ -22,6 +22,7 @@
 #include "PackageInfoResolver.h"
 
 #include <WatchdogProperties.sysprop.h>
+#include <android-base/file.h>
 #include <android/automotive/watchdog/internal/PackageIdentifier.h>
 #include <android/automotive/watchdog/internal/UidType.h>
 #include <binder/IPCThreadState.h>
@@ -45,6 +46,7 @@
 using ::android::automotive::watchdog::internal::UidType;
 using ::android::base::Error;
 using ::android::base::Result;
+using ::android::base::WriteStringToFd;
 using ::android::binder::Status;
 
 // Minimum written bytes to sync the stats with the Watchdog service.
@@ -53,6 +55,10 @@
 constexpr double kDefaultIoOveruseWarnPercentage = 80;
 // Maximum numer of system-wide stats (from periodic monitoring) to cache.
 constexpr size_t kMaxPeriodicMonitorBufferSize = 1000;
+constexpr const char* kHelpText =
+        "\n%s dump options:\n"
+        "%s <package name>, <package name>,...: Reset resource overuse stats for the given package "
+        "names. Value for this flag is a comma-separated value containing package names.\n";
 
 namespace {
 
@@ -101,7 +107,7 @@
 }
 
 IoOveruseMonitor::IoOveruseMonitor(
-        const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper) :
+        const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper) :
       mMinSyncWrittenBytes(kMinSyncWrittenBytes),
       mWatchdogServiceHelper(watchdogServiceHelper),
       mSystemWideWrittenBytes({}),
@@ -310,7 +316,8 @@
     if (const auto status = mWatchdogServiceHelper->latestIoOveruseStats(mLatestIoOveruseStats);
         !status.isOk()) {
         // Don't clear the cache as it can be pushed again on the next collection.
-        ALOGW("Failed to push the latest I/O overuse stats to watchdog service");
+        ALOGW("Failed to push the latest I/O overuse stats to watchdog service: %s",
+              status.toString8().c_str());
     } else {
         mLatestIoOveruseStats.clear();
         if (DEBUG) {
@@ -394,6 +401,11 @@
     return {};
 }
 
+bool IoOveruseMonitor::dumpHelpText(int fd) {
+    return WriteStringToFd(StringPrintf(kHelpText, name().c_str(), kResetResourceOveruseStatsFlag),
+                           fd);
+}
+
 void IoOveruseMonitor::notifyNativePackagesLocked(
         const std::unordered_map<uid_t, IoOveruseStats>& statsByUid) {
     for (const auto& [uid, ioOveruseStats] : statsByUid) {
@@ -521,6 +533,23 @@
     return {};
 }
 
+Result<void> IoOveruseMonitor::resetIoOveruseStats(const std::vector<std::string>& packageNames) {
+    if (const auto status = mWatchdogServiceHelper->resetResourceOveruseStats(packageNames);
+        !status.isOk()) {
+        return Error() << "Failed to reset stats in watchdog service: " << status.toString8();
+    }
+    std::unordered_set<std::string> uniquePackageNames;
+    std::copy(packageNames.begin(), packageNames.end(),
+              std::inserter(uniquePackageNames, uniquePackageNames.end()));
+    for (auto& [key, usage] : mUserPackageDailyIoUsageById) {
+        if (uniquePackageNames.find(usage.packageInfo.packageIdentifier.name) !=
+            uniquePackageNames.end()) {
+            usage.resetStats();
+        }
+    }
+    return {};
+}
+
 void IoOveruseMonitor::handleBinderDeath(const wp<IBinder>& who) {
     std::unique_lock writeLock(mRwMutex);
     IBinder* binder = who.unsafe_get();
@@ -582,6 +611,14 @@
     return uniquePackageIdStr(packageInfo.packageIdentifier);
 }
 
+void IoOveruseMonitor::UserPackageIoUsage::resetStats() {
+    writtenBytes = {};
+    forgivenWriteBytes = {};
+    totalOveruses = 0;
+    isPackageWarned = false;
+    lastSyncedWrittenBytes = 0;
+}
+
 }  // namespace watchdog
 }  // namespace automotive
 }  // namespace android
diff --git a/cpp/watchdog/server/src/IoOveruseMonitor.h b/cpp/watchdog/server/src/IoOveruseMonitor.h
index 7040353..e749eec 100644
--- a/cpp/watchdog/server/src/IoOveruseMonitor.h
+++ b/cpp/watchdog/server/src/IoOveruseMonitor.h
@@ -49,6 +49,8 @@
 
 // Number of periodically monitored stats to cache in memory.
 constexpr int32_t kDefaultPeriodicMonitorBufferSize = 360;
+// Dumpsys flags.
+constexpr const char* kResetResourceOveruseStatsFlag = "--reset_resource_overuse_stats";
 
 // Forward declaration for testing use only.
 namespace internal {
@@ -69,6 +71,9 @@
     // Returns whether or not the monitor is initialized.
     virtual bool isInitialized() = 0;
 
+    // Dumps the help text.
+    virtual bool dumpHelpText(int fd) = 0;
+
     // Below API is from internal/ICarWatchdog.aidl. Please refer to the AIDL for description.
     virtual android::base::Result<void> updateResourceOveruseConfigurations(
             const std::vector<
@@ -90,12 +95,14 @@
             const sp<IResourceOveruseListener>& listener) = 0;
 
     virtual android::base::Result<void> getIoOveruseStats(IoOveruseStats* ioOveruseStats) = 0;
+
+    virtual android::base::Result<void> resetIoOveruseStats(
+            const std::vector<std::string>& packageNames) = 0;
 };
 
 class IoOveruseMonitor final : public IIoOveruseMonitor {
 public:
-    explicit IoOveruseMonitor(
-            const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper);
+    explicit IoOveruseMonitor(const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper);
 
     ~IoOveruseMonitor() { terminate(); }
 
@@ -140,6 +147,8 @@
 
     android::base::Result<void> onDump(int fd);
 
+    bool dumpHelpText(int fd);
+
     android::base::Result<void> onCustomCollectionDump(int /*fd*/) {
         // No special processing for custom collection. Thus no custom collection dump.
         return {};
@@ -167,6 +176,8 @@
 
     android::base::Result<void> getIoOveruseStats(IoOveruseStats* ioOveruseStats);
 
+    android::base::Result<void> resetIoOveruseStats(const std::vector<std::string>& packageName);
+
 protected:
     android::base::Result<void> init();
 
@@ -191,6 +202,7 @@
         UserPackageIoUsage& operator+=(const UserPackageIoUsage& r);
 
         const std::string id() const;
+        void resetStats();
     };
 
     class BinderDeathRecipient final : public android::IBinder::DeathRecipient {
@@ -221,7 +233,7 @@
     sp<IPackageInfoResolver> mPackageInfoResolver;
     // Minimum written bytes to sync the stats with the Watchdog service.
     double mMinSyncWrittenBytes;
-    android::sp<IWatchdogServiceHelperInterface> mWatchdogServiceHelper;
+    android::sp<IWatchdogServiceHelper> mWatchdogServiceHelper;
 
     // Makes sure only one collection is running at any given time.
     mutable std::shared_mutex mRwMutex;
@@ -237,7 +249,7 @@
     size_t mPeriodicMonitorBufferSize GUARDED_BY(mRwMutex);
     time_t mLastSystemWideIoMonitorTime GUARDED_BY(mRwMutex);
 
-    // Cache of per user package I/O usage.
+    // Cache of per user package I/O usage. Key is a unique ID with the format `packageName:userId`.
     std::unordered_map<std::string, UserPackageIoUsage> mUserPackageDailyIoUsageById
             GUARDED_BY(mRwMutex);
     double mIoOveruseWarnPercentage GUARDED_BY(mRwMutex);
diff --git a/cpp/watchdog/server/src/PackageInfoResolver.cpp b/cpp/watchdog/server/src/PackageInfoResolver.cpp
index 1a4346a..2b30600 100644
--- a/cpp/watchdog/server/src/PackageInfoResolver.cpp
+++ b/cpp/watchdog/server/src/PackageInfoResolver.cpp
@@ -109,7 +109,7 @@
 }
 
 Result<void> PackageInfoResolver::initWatchdogServiceHelper(
-        const sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper) {
+        const sp<IWatchdogServiceHelper>& watchdogServiceHelper) {
     std::unique_lock writeLock(mRWMutex);
     if (watchdogServiceHelper == nullptr) {
         return Error() << "Must provide a non-null watchdog service helper instance";
diff --git a/cpp/watchdog/server/src/PackageInfoResolver.h b/cpp/watchdog/server/src/PackageInfoResolver.h
index e13f47b..c1bba4d 100644
--- a/cpp/watchdog/server/src/PackageInfoResolver.h
+++ b/cpp/watchdog/server/src/PackageInfoResolver.h
@@ -59,7 +59,7 @@
 
 protected:
     virtual android::base::Result<void> initWatchdogServiceHelper(
-            const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper) = 0;
+            const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper) = 0;
     virtual void setPackageConfigurations(
             const std::unordered_set<std::string>& vendorPackagePrefixes,
             const std::unordered_map<
@@ -112,7 +112,7 @@
     static void terminate();
 
     android::base::Result<void> initWatchdogServiceHelper(
-            const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper);
+            const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper);
 
     virtual void setPackageConfigurations(
             const std::unordered_set<std::string>& vendorPackagePrefixes,
@@ -141,7 +141,7 @@
      * thread. In order to avoid a race condition between |initWatchdogServiceHelper| and
      * |getPackage*ForUids| calls, mWatchdogServiceHelper is guarded by a read-write lock.
      */
-    android::sp<IWatchdogServiceHelperInterface> mWatchdogServiceHelper GUARDED_BY(mRWMutex);
+    android::sp<IWatchdogServiceHelper> mWatchdogServiceHelper GUARDED_BY(mRWMutex);
     std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>
             mUidToPackageInfoMapping GUARDED_BY(mRWMutex);
     std::vector<std::string> mVendorPackagePrefixes GUARDED_BY(mRWMutex);
diff --git a/cpp/watchdog/server/src/ServiceManager.cpp b/cpp/watchdog/server/src/ServiceManager.cpp
index 6bcba40..a50167b 100644
--- a/cpp/watchdog/server/src/ServiceManager.cpp
+++ b/cpp/watchdog/server/src/ServiceManager.cpp
@@ -34,7 +34,7 @@
 sp<WatchdogProcessService> ServiceManager::sWatchdogProcessService = nullptr;
 sp<WatchdogPerfService> ServiceManager::sWatchdogPerfService = nullptr;
 sp<WatchdogBinderMediator> ServiceManager::sWatchdogBinderMediator = nullptr;
-sp<IWatchdogServiceHelperInterface> ServiceManager::sWatchdogServiceHelper = nullptr;
+sp<IWatchdogServiceHelper> ServiceManager::sWatchdogServiceHelper = nullptr;
 
 Result<void> ServiceManager::startServices(const sp<Looper>& looper) {
     if (sWatchdogBinderMediator != nullptr || sWatchdogServiceHelper != nullptr ||
diff --git a/cpp/watchdog/server/src/ServiceManager.h b/cpp/watchdog/server/src/ServiceManager.h
index a536121..a0cc4d4 100644
--- a/cpp/watchdog/server/src/ServiceManager.h
+++ b/cpp/watchdog/server/src/ServiceManager.h
@@ -44,7 +44,7 @@
     static android::sp<WatchdogProcessService> sWatchdogProcessService;
     static android::sp<WatchdogPerfService> sWatchdogPerfService;
     static android::sp<WatchdogBinderMediator> sWatchdogBinderMediator;
-    static android::sp<IWatchdogServiceHelperInterface> sWatchdogServiceHelper;
+    static android::sp<IWatchdogServiceHelper> sWatchdogServiceHelper;
 };
 
 }  // namespace watchdog
diff --git a/cpp/watchdog/server/src/WatchdogBinderMediator.cpp b/cpp/watchdog/server/src/WatchdogBinderMediator.cpp
index 0a4eb25..f3fba35 100644
--- a/cpp/watchdog/server/src/WatchdogBinderMediator.cpp
+++ b/cpp/watchdog/server/src/WatchdogBinderMediator.cpp
@@ -37,6 +37,7 @@
 using ::android::base::Join;
 using ::android::base::ParseUint;
 using ::android::base::Result;
+using ::android::base::Split;
 using ::android::base::StringAppendF;
 using ::android::base::StringPrintf;
 using ::android::base::WriteStringToFd;
@@ -79,7 +80,7 @@
 WatchdogBinderMediator::WatchdogBinderMediator(
         const android::sp<WatchdogProcessService>& watchdogProcessService,
         const android::sp<WatchdogPerfService>& watchdogPerfService,
-        const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper,
+        const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper,
         const AddServiceFunction& addServiceHandler) :
       mWatchdogProcessService(watchdogProcessService),
       mWatchdogPerfService(watchdogPerfService),
@@ -131,60 +132,73 @@
 
 status_t WatchdogBinderMediator::dump(int fd, const Vector<String16>& args) {
     int numArgs = args.size();
-    if (numArgs == 1 && (args[0] == String16(kHelpFlag) || args[0] == String16(kHelpShortFlag))) {
-        if (!dumpHelpText(fd, "")) {
-            ALOGW("Failed to write help text to fd");
-            return FAILED_TRANSACTION;
-        }
-        return OK;
+    if (numArgs == 0) {
+        return dumpServices(fd, args);
     }
-    if (numArgs >= 1 &&
-        (args[0] == String16(kStartCustomCollectionFlag) ||
-         args[0] == String16(kEndCustomCollectionFlag))) {
-        auto ret = mWatchdogPerfService->onCustomCollection(fd, args);
-        if (!ret.ok()) {
+    if (numArgs == 1 && (args[0] == String16(kHelpFlag) || args[0] == String16(kHelpShortFlag))) {
+        return dumpHelpText(fd, "");
+    }
+    if (args[0] == String16(kStartCustomCollectionFlag) ||
+        args[0] == String16(kEndCustomCollectionFlag)) {
+        if (auto result = mWatchdogPerfService->onCustomCollection(fd, args); !result.ok()) {
             std::string mode = args[0] == String16(kStartCustomCollectionFlag) ? "start" : "end";
             std::string errorMsg = StringPrintf("Failed to %s custom I/O perf collection: %s",
-                                                mode.c_str(), ret.error().message().c_str());
-            if (ret.error().code() == BAD_VALUE) {
+                                                mode.c_str(), result.error().message().c_str());
+            if (result.error().code() == BAD_VALUE) {
                 dumpHelpText(fd, errorMsg);
             } else {
                 ALOGW("%s", errorMsg.c_str());
             }
-            return ret.error().code();
+            return result.error().code();
         }
         return OK;
     }
-
-    if (numArgs > 0) {
-        ALOGW("Car watchdog cannot recognize the given option(%s). Dumping the current state...",
-              Join(args, " ").c_str());
+    if (numArgs == 2 && args[0] == String16(kResetResourceOveruseStatsFlag)) {
+        std::string value = std::string(String8(args[1]));
+        std::vector<std::string> packageNames = Split(value, ",");
+        if (value.empty() || packageNames.empty()) {
+            dumpHelpText(fd,
+                         StringPrintf("Must provide valid package names: [%s]\n", value.c_str()));
+            return BAD_VALUE;
+        }
+        if (auto result = mIoOveruseMonitor->resetIoOveruseStats(packageNames); !result.ok()) {
+            ALOGW("Failed to reset stats for packages: [%s]", value.c_str());
+            return FAILED_TRANSACTION;
+        }
+        return OK;
     }
+    dumpHelpText(fd,
+                 StringPrintf("Invalid carwatchdog dumpsys options: [%s]\n",
+                              Join(args, " ").c_str()));
+    return dumpServices(fd, args);
+}
 
-    auto ret = mWatchdogProcessService->dump(fd, args);
-    if (!ret.ok()) {
-        ALOGW("Failed to dump carwatchdog process service: %s", ret.error().message().c_str());
-        return ret.error().code();
+status_t WatchdogBinderMediator::dumpServices(int fd, const Vector<String16>& args) {
+    if (auto result = mWatchdogProcessService->dump(fd, args); !result.ok()) {
+        ALOGW("Failed to dump carwatchdog process service: %s", result.error().message().c_str());
+        return result.error().code();
     }
-    ret = mWatchdogPerfService->onDump(fd);
-    if (!ret.ok()) {
-        ALOGW("Failed to dump I/O perf collection: %s", ret.error().message().c_str());
-        return ret.error().code();
+    if (auto result = mWatchdogPerfService->onDump(fd); !result.ok()) {
+        ALOGW("Failed to dump carwatchdog perf service: %s", result.error().message().c_str());
+        return result.error().code();
     }
     return OK;
 }
 
-bool WatchdogBinderMediator::dumpHelpText(int fd, std::string errorMsg) {
+status_t WatchdogBinderMediator::dumpHelpText(const int fd, const std::string& errorMsg) {
     if (!errorMsg.empty()) {
         ALOGW("Error: %s", errorMsg.c_str());
         if (!WriteStringToFd(StringPrintf("Error: %s\n\n", errorMsg.c_str()), fd)) {
             ALOGW("Failed to write error message to fd");
-            return false;
+            return FAILED_TRANSACTION;
         }
     }
-
-    return WriteStringToFd(StringPrintf(kHelpText, kHelpFlag, kHelpShortFlag), fd) &&
-            mWatchdogPerfService->dumpHelpText(fd);
+    if (!WriteStringToFd(StringPrintf(kHelpText, kHelpFlag, kHelpShortFlag), fd) ||
+        !mWatchdogPerfService->dumpHelpText(fd) || !mIoOveruseMonitor->dumpHelpText(fd)) {
+        ALOGW("Failed to write help text to fd");
+        return FAILED_TRANSACTION;
+    }
+    return OK;
 }
 
 Status WatchdogBinderMediator::registerClient(const sp<ICarWatchdogClient>& client,
diff --git a/cpp/watchdog/server/src/WatchdogBinderMediator.h b/cpp/watchdog/server/src/WatchdogBinderMediator.h
index 63b687b..2123520 100644
--- a/cpp/watchdog/server/src/WatchdogBinderMediator.h
+++ b/cpp/watchdog/server/src/WatchdogBinderMediator.h
@@ -56,13 +56,12 @@
 // the calls either to process ANR or performance services.
 class WatchdogBinderMediator : public BnCarWatchdog {
 public:
-    WatchdogBinderMediator(
-            const android::sp<WatchdogProcessService>& watchdogProcessService,
-            const android::sp<WatchdogPerfService>& watchdogPerfService,
-            const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper,
-            const std::function<android::base::Result<void>(const char*,
-                                                            const android::sp<android::IBinder>&)>&
-                    addServiceHandler = nullptr);
+    WatchdogBinderMediator(const android::sp<WatchdogProcessService>& watchdogProcessService,
+                           const android::sp<WatchdogPerfService>& watchdogPerfService,
+                           const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper,
+                           const std::function<android::base::Result<void>(
+                                   const char*, const android::sp<android::IBinder>&)>&
+                                   addServiceHandler = nullptr);
     ~WatchdogBinderMediator() { terminate(); }
 
     // Implements ICarWatchdog.aidl APIs.
@@ -113,7 +112,8 @@
     }
 
 private:
-    bool dumpHelpText(int fd, std::string errorMsg);
+    status_t dumpServices(int fd, const Vector<String16>& args);
+    status_t dumpHelpText(const int fd, const std::string& errorMsg);
 
     android::sp<WatchdogProcessService> mWatchdogProcessService;
     android::sp<WatchdogPerfService> mWatchdogPerfService;
diff --git a/cpp/watchdog/server/src/WatchdogInternalHandler.h b/cpp/watchdog/server/src/WatchdogInternalHandler.h
index 098b0dd..1f417e7 100644
--- a/cpp/watchdog/server/src/WatchdogInternalHandler.h
+++ b/cpp/watchdog/server/src/WatchdogInternalHandler.h
@@ -45,7 +45,7 @@
 public:
     explicit WatchdogInternalHandler(
             const android::sp<WatchdogBinderMediator>& binderMediator,
-            const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper,
+            const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper,
             const android::sp<WatchdogProcessService>& watchdogProcessService,
             const android::sp<WatchdogPerfService>& watchdogPerfService,
             const android::sp<IIoOveruseMonitor>& ioOveruseMonitor) :
@@ -107,7 +107,7 @@
     void checkAndRegisterIoOveruseMonitor();
 
     android::sp<WatchdogBinderMediator> mBinderMediator;
-    android::sp<IWatchdogServiceHelperInterface> mWatchdogServiceHelper;
+    android::sp<IWatchdogServiceHelper> mWatchdogServiceHelper;
     android::sp<WatchdogProcessService> mWatchdogProcessService;
     android::sp<WatchdogPerfService> mWatchdogPerfService;
     android::sp<IIoOveruseMonitor> mIoOveruseMonitor;
diff --git a/cpp/watchdog/server/src/WatchdogPerfService.cpp b/cpp/watchdog/server/src/WatchdogPerfService.cpp
index 214a16c..030f318 100644
--- a/cpp/watchdog/server/src/WatchdogPerfService.cpp
+++ b/cpp/watchdog/server/src/WatchdogPerfService.cpp
@@ -68,7 +68,7 @@
         "\t%s <seconds>: Modifies the maximum collection duration. Default behavior is to collect "
         "until %ld minutes before automatically stopping the custom collection and discarding "
         "the collected data.\n"
-        "\t%s <package name>,<package, name>,...: Comma-separated value containing package names. "
+        "\t%s <package name>,<package name>,...: Comma-separated value containing package names. "
         "When provided, the results are filtered only to the provided package names. Default "
         "behavior is to list the results for the top N packages.\n"
         "%s: Stops custom performance data collection and generates a dump of "
diff --git a/cpp/watchdog/server/src/WatchdogProcessService.cpp b/cpp/watchdog/server/src/WatchdogProcessService.cpp
index 952c83e..b84f5a2 100644
--- a/cpp/watchdog/server/src/WatchdogProcessService.cpp
+++ b/cpp/watchdog/server/src/WatchdogProcessService.cpp
@@ -140,7 +140,7 @@
     }
 }
 Result<void> WatchdogProcessService::registerWatchdogServiceHelper(
-        const sp<IWatchdogServiceHelperInterface>& helper) {
+        const sp<IWatchdogServiceHelper>& helper) {
     if (helper == nullptr) {
         return Error() << "Must provide a non-null watchdog service helper instance";
     }
diff --git a/cpp/watchdog/server/src/WatchdogProcessService.h b/cpp/watchdog/server/src/WatchdogProcessService.h
index 288f99e..fcc1b3d 100644
--- a/cpp/watchdog/server/src/WatchdogProcessService.h
+++ b/cpp/watchdog/server/src/WatchdogProcessService.h
@@ -41,7 +41,7 @@
 namespace automotive {
 namespace watchdog {
 
-class IWatchdogServiceHelperInterface;
+class IWatchdogServiceHelper;
 
 class WatchdogProcessService : public android::RefBase {
 public:
@@ -55,7 +55,7 @@
     void doHealthCheck(int what);
 
     virtual android::base::Result<void> registerWatchdogServiceHelper(
-            const android::sp<IWatchdogServiceHelperInterface>& helper);
+            const android::sp<IWatchdogServiceHelper>& helper);
 
     virtual android::binder::Status registerClient(const android::sp<ICarWatchdogClient>& client,
                                                    TimeoutLength timeout);
@@ -95,7 +95,7 @@
               userId(userId),
               type(ClientType::Regular),
               client(client) {}
-        ClientInfo(const android::sp<IWatchdogServiceHelperInterface>& helper,
+        ClientInfo(const android::sp<IWatchdogServiceHelper>& helper,
                    const android::sp<android::IBinder>& binder, pid_t pid, userid_t userId) :
               pid(pid),
               userId(userId),
@@ -125,7 +125,7 @@
 
         ClientType type;
         android::sp<ICarWatchdogClient> client = nullptr;
-        android::sp<IWatchdogServiceHelperInterface> watchdogServiceHelper = nullptr;
+        android::sp<IWatchdogServiceHelper> watchdogServiceHelper = nullptr;
         android::sp<IBinder> watchdogServiceBinder = nullptr;
     };
 
@@ -246,7 +246,7 @@
             mNotSupportedVhalProperties;
     android::sp<PropertyChangeListener> mPropertyChangeListener;
     HeartBeat mVhalHeartBeat GUARDED_BY(mMutex);
-    android::sp<IWatchdogServiceHelperInterface> mWatchdogServiceHelper GUARDED_BY(mMutex);
+    android::sp<IWatchdogServiceHelper> mWatchdogServiceHelper GUARDED_BY(mMutex);
 };
 
 }  // namespace watchdog
diff --git a/cpp/watchdog/server/src/WatchdogServiceHelper.cpp b/cpp/watchdog/server/src/WatchdogServiceHelper.cpp
index 03f3305..4c1258f 100644
--- a/cpp/watchdog/server/src/WatchdogServiceHelper.cpp
+++ b/cpp/watchdog/server/src/WatchdogServiceHelper.cpp
@@ -203,6 +203,17 @@
     return service->latestIoOveruseStats(packageIoOveruseStats);
 }
 
+Status WatchdogServiceHelper::resetResourceOveruseStats(
+        const std::vector<std::string>& packageNames) {
+    sp<ICarWatchdogServiceForSystem> service;
+    if (std::shared_lock readLock(mRWMutex); mService == nullptr) {
+        return fromExceptionCode(Status::EX_ILLEGAL_STATE, "Watchdog service is not initialized");
+    } else {
+        service = mService;
+    }
+    return service->resetResourceOveruseStats(packageNames);
+}
+
 }  // namespace watchdog
 }  // namespace automotive
 }  // namespace android
diff --git a/cpp/watchdog/server/src/WatchdogServiceHelper.h b/cpp/watchdog/server/src/WatchdogServiceHelper.h
index 03796f0..390013a 100644
--- a/cpp/watchdog/server/src/WatchdogServiceHelper.h
+++ b/cpp/watchdog/server/src/WatchdogServiceHelper.h
@@ -45,7 +45,7 @@
 
 }  // namespace internal
 
-class IWatchdogServiceHelperInterface : public android::IBinder::DeathRecipient {
+class IWatchdogServiceHelper : public android::IBinder::DeathRecipient {
 public:
     virtual android::binder::Status registerService(
             const android::sp<
@@ -68,6 +68,8 @@
     virtual android::binder::Status latestIoOveruseStats(
             const std::vector<android::automotive::watchdog::internal::PackageIoOveruseStats>&
                     packageIoOveruseStats) = 0;
+    virtual android::binder::Status resetResourceOveruseStats(
+            const std::vector<std::string>& packageNames) = 0;
 
 protected:
     virtual android::base::Result<void> init(
@@ -81,7 +83,7 @@
 // WatchdogServiceHelper implements the helper functions for the outbound API requests to
 // the CarWatchdogService. This class doesn't handle the inbound APIs requests from
 // CarWatchdogService except the registration APIs.
-class WatchdogServiceHelper final : public IWatchdogServiceHelperInterface {
+class WatchdogServiceHelper final : public IWatchdogServiceHelper {
 public:
     WatchdogServiceHelper() : mService(nullptr), mWatchdogProcessService(nullptr) {}
     ~WatchdogServiceHelper();
@@ -107,6 +109,7 @@
     android::binder::Status latestIoOveruseStats(
             const std::vector<android::automotive::watchdog::internal::PackageIoOveruseStats>&
                     packageIoOveruseStats);
+    android::binder::Status resetResourceOveruseStats(const std::vector<std::string>& packageNames);
 
 protected:
     android::base::Result<void> init(
diff --git a/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp b/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
index 89dd263..a308126 100644
--- a/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
+++ b/cpp/watchdog/server/tests/IoOveruseMonitorTest.cpp
@@ -37,8 +37,6 @@
 
 using ::android::IPCThreadState;
 using ::android::RefBase;
-using ::android::automotive::watchdog::internal::ApplicationCategoryType;
-using ::android::automotive::watchdog::internal::ComponentType;
 using ::android::automotive::watchdog::internal::IoOveruseAlertThreshold;
 using ::android::automotive::watchdog::internal::PackageIdentifier;
 using ::android::automotive::watchdog::internal::PackageInfo;
@@ -48,14 +46,11 @@
 using ::android::base::StringAppendF;
 using ::android::binder::Status;
 using ::testing::_;
-using ::testing::AllOf;
 using ::testing::DoAll;
-using ::testing::Field;
 using ::testing::Return;
 using ::testing::ReturnRef;
 using ::testing::SaveArg;
 using ::testing::UnorderedElementsAreArray;
-using ::testing::Value;
 
 namespace {
 
@@ -208,6 +203,41 @@
         mIoOveruseMonitorPeer.clear();
     }
 
+    void setUpPackagesAndConfigurations() {
+        std::unordered_map<uid_t, PackageInfo> packageInfoMapping =
+                {{1001000,
+                  constructPackageInfo(
+                          /*packageName=*/"system.daemon", /*uid=*/1001000, UidType::NATIVE)},
+                 {1112345,
+                  constructPackageInfo(
+                          /*packageName=*/"com.android.google.package", /*uid=*/1112345,
+                          UidType::APPLICATION)},
+                 {1113999,
+                  constructPackageInfo(
+                          /*packageName=*/"com.android.google.package", /*uid=*/1113999,
+                          UidType::APPLICATION)},
+                 {1212345,
+                  constructPackageInfo(
+                          /*packageName=*/"com.android.google.package", /*uid=*/1212345,
+                          UidType::APPLICATION)},
+                 {1312345,
+                  constructPackageInfo(
+                          /*packageName=*/"com.android.google.package", /*uid=*/1312345,
+                          UidType::APPLICATION)}};
+        ON_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_))
+                .WillByDefault(Return(packageInfoMapping));
+        mMockIoOveruseConfigs->injectPackageConfigs({
+                {"system.daemon",
+                 {constructPerStateBytes(/*fgBytes=*/80'000, /*bgBytes=*/40'000,
+                                         /*gmBytes=*/100'000),
+                  /*isSafeToKill=*/false}},
+                {"com.android.google.package",
+                 {constructPerStateBytes(/*fgBytes=*/70'000, /*bgBytes=*/30'000,
+                                         /*gmBytes=*/100'000),
+                  /*isSafeToKill=*/true}},
+        });
+    }
+
     void executeAsUid(uid_t uid, std::function<void()> func) {
         sp<ScopedChangeCallingUid> scopedChangeCallingUid = new ScopedChangeCallingUid(uid);
         ASSERT_NO_FATAL_FAILURE(func());
@@ -221,33 +251,7 @@
 };
 
 TEST_F(IoOveruseMonitorTest, TestOnPeriodicCollection) {
-    std::unordered_map<uid_t, PackageInfo> packageInfoMapping =
-            {{1001000,
-              constructPackageInfo(
-                      /*packageName=*/"system.daemon", /*uid=*/1001000, UidType::NATIVE)},
-             {1112345,
-              constructPackageInfo(
-                      /*packageName=*/"com.android.google.package", /*uid=*/1112345,
-                      UidType::APPLICATION)},
-             {1212345,
-              constructPackageInfo(
-                      /*packageName=*/"com.android.google.package", /*uid=*/1212345,
-                      UidType::APPLICATION)},
-             {1113999,
-              constructPackageInfo(
-                      /*packageName=*/"com.android.google.package", /*uid=*/1113999,
-                      UidType::APPLICATION)}};
-    ON_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_))
-            .WillByDefault(Return(packageInfoMapping));
-    mMockIoOveruseConfigs->injectPackageConfigs({
-            {"system.daemon",
-             {constructPerStateBytes(/*fgBytes=*/80'000, /*bgBytes=*/40'000, /*gmBytes=*/100'000),
-              /*isSafeToKill=*/false}},
-            {"com.android.google.package",
-             {constructPerStateBytes(/*fgBytes=*/70'000, /*bgBytes=*/30'000, /*gmBytes=*/100'000),
-              /*isSafeToKill=*/true}},
-    });
-
+    setUpPackagesAndConfigurations();
     sp<MockResourceOveruseListener> mockResourceOveruseListener = new MockResourceOveruseListener();
     ASSERT_NO_FATAL_FAILURE(executeAsUid(1001000, [&]() {
         ASSERT_RESULT_OK(mIoOveruseMonitor->addIoOveruseListener(mockResourceOveruseListener));
@@ -404,32 +408,7 @@
 }
 
 TEST_F(IoOveruseMonitorTest, TestOnPeriodicCollectionWithSmallWrittenBytes) {
-    std::unordered_map<uid_t, PackageInfo> packageInfoMapping =
-            {{1001000,
-              constructPackageInfo(
-                      /*packageName=*/"system.daemon", /*uid=*/1001000, UidType::NATIVE)},
-             {1112345,
-              constructPackageInfo(
-                      /*packageName=*/"com.android.google.package", /*uid=*/1112345,
-                      UidType::APPLICATION)},
-             {1212345,
-              constructPackageInfo(
-                      /*packageName=*/"com.android.google.package", /*uid=*/1212345,
-                      UidType::APPLICATION)},
-             {1312345,
-              constructPackageInfo(
-                      /*packageName=*/"com.android.google.package", /*uid=*/1312345,
-                      UidType::APPLICATION)}};
-    EXPECT_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_))
-            .WillRepeatedly(Return(packageInfoMapping));
-    mMockIoOveruseConfigs->injectPackageConfigs(
-            {{"system.daemon",
-              {constructPerStateBytes(/*fgBytes=*/80'000, /*bgBytes=*/40'000, /*gmBytes=*/100'000),
-               /*isSafeToKill=*/false}},
-             {"com.android.google.package",
-              {constructPerStateBytes(/*fgBytes=*/70'000, /*bgBytes=*/30'000, /*gmBytes=*/100'000),
-               /*isSafeToKill=*/true}}});
-
+    setUpPackagesAndConfigurations();
     sp<MockUidIoStats> mockUidIoStats = new MockUidIoStats();
     /*
      * UID 1212345 current written bytes < |KTestMinSyncWrittenBytes| so the UID's stats are not
@@ -657,18 +636,7 @@
 }
 
 TEST_F(IoOveruseMonitorTest, TestGetIoOveruseStats) {
-    // Setup internal counters for a package.
-    ON_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_))
-            .WillByDefault([]() -> std::unordered_map<uid_t, PackageInfo> {
-                return {{1001000,
-                         constructPackageInfo(/*packageName=*/"system.daemon", /*uid=*/1001000,
-                                              UidType::NATIVE)}};
-            });
-    mMockIoOveruseConfigs->injectPackageConfigs(
-            {{"system.daemon",
-              {constructPerStateBytes(/*fgBytes=*/80'000, /*bgBytes=*/40'000,
-                                      /*gmBytes=*/100'000),
-               /*isSafeToKill=*/false}}});
+    setUpPackagesAndConfigurations();
     sp<MockUidIoStats> mockUidIoStats = new MockUidIoStats();
     mockUidIoStats->expectDeltaStats(
             {{1001000, IoUsage(0, 0, /*fgWrBytes=*/90'000, /*bgWrBytes=*/20'000, 0, 0)}});
@@ -694,6 +662,50 @@
                                   << "\nActual: " << actual.toString();
 }
 
+TEST_F(IoOveruseMonitorTest, TestResetIoOveruseStats) {
+    setUpPackagesAndConfigurations();
+    sp<MockUidIoStats> mockUidIoStats = new MockUidIoStats();
+    mockUidIoStats->expectDeltaStats(
+            {{1001000, IoUsage(0, 0, /*fgWrBytes=*/90'000, /*bgWrBytes=*/20'000, 0, 0)}});
+
+    ASSERT_RESULT_OK(
+            mIoOveruseMonitor->onPeriodicCollection(std::chrono::system_clock::to_time_t(
+                                                            std::chrono::system_clock::now()),
+                                                    mockUidIoStats, nullptr, nullptr));
+
+    IoOveruseStats actual;
+    ASSERT_NO_FATAL_FAILURE(executeAsUid(1001000, [&]() {
+        ASSERT_RESULT_OK(mIoOveruseMonitor->getIoOveruseStats(&actual));
+    }));
+
+    EXPECT_NE(actual.totalOveruses, 0);
+    EXPECT_NE(actual.writtenBytes.foregroundBytes, 0);
+    EXPECT_NE(actual.writtenBytes.backgroundBytes, 0);
+
+    std::vector<std::string> packageNames = {"system.daemon"};
+    EXPECT_CALL(*mMockWatchdogServiceHelper, resetResourceOveruseStats(packageNames))
+            .WillOnce(Return(Status::ok()));
+
+    ASSERT_RESULT_OK(mIoOveruseMonitor->resetIoOveruseStats(packageNames));
+
+    ASSERT_NO_FATAL_FAILURE(executeAsUid(1001000, [&]() {
+        ASSERT_RESULT_OK(mIoOveruseMonitor->getIoOveruseStats(&actual));
+    }));
+
+    EXPECT_EQ(actual.totalOveruses, 0);
+    EXPECT_EQ(actual.writtenBytes.foregroundBytes, 0);
+    EXPECT_EQ(actual.writtenBytes.backgroundBytes, 0);
+}
+
+TEST_F(IoOveruseMonitorTest, TestErrorsResetIoOveruseStatsOnWatchdogServiceHelperError) {
+    std::vector<std::string> packageNames = {"system.daemon"};
+    EXPECT_CALL(*mMockWatchdogServiceHelper, resetResourceOveruseStats(packageNames))
+            .WillOnce(Return(Status::fromExceptionCode(Status::EX_ILLEGAL_STATE)));
+
+    ASSERT_FALSE(mIoOveruseMonitor->resetIoOveruseStats(packageNames).ok())
+            << "Must return error when WatchdogServiceHelper fails to reset stats";
+}
+
 TEST_F(IoOveruseMonitorTest, TestErrorsGetIoOveruseStatsOnNoStats) {
     ON_CALL(*mMockPackageInfoResolver, getPackageInfosForUids(_))
             .WillByDefault([]() -> std::unordered_map<uid_t, PackageInfo> {
diff --git a/cpp/watchdog/server/tests/MockCarWatchdogServiceForSystem.h b/cpp/watchdog/server/tests/MockCarWatchdogServiceForSystem.h
index c8f1614..d484463 100644
--- a/cpp/watchdog/server/tests/MockCarWatchdogServiceForSystem.h
+++ b/cpp/watchdog/server/tests/MockCarWatchdogServiceForSystem.h
@@ -51,6 +51,8 @@
             android::binder::Status, latestIoOveruseStats,
             (const std::vector<android::automotive::watchdog::internal::PackageIoOveruseStats>&),
             (override));
+    MOCK_METHOD(android::binder::Status, resetResourceOveruseStats,
+                (const std::vector<std::string>&), (override));
 
 private:
     android::sp<MockBinder> mBinder;
diff --git a/cpp/watchdog/server/tests/MockIoOveruseMonitor.h b/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
index cb7d0c5..79ba932 100644
--- a/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
+++ b/cpp/watchdog/server/tests/MockIoOveruseMonitor.h
@@ -36,6 +36,7 @@
     }
     ~MockIoOveruseMonitor() {}
     MOCK_METHOD(bool, isInitialized, (), (override));
+    MOCK_METHOD(bool, dumpHelpText, (int), (override));
     MOCK_METHOD(android::base::Result<void>, updateResourceOveruseConfigurations,
                 (const std::vector<
                         android::automotive::watchdog::internal::ResourceOveruseConfiguration>&),
@@ -54,6 +55,8 @@
     MOCK_METHOD(android::base::Result<void>, removeIoOveruseListener,
                 (const sp<IResourceOveruseListener>&), (override));
     MOCK_METHOD(android::base::Result<void>, getIoOveruseStats, (IoOveruseStats*), (override));
+    MOCK_METHOD(android::base::Result<void>, resetIoOveruseStats, (const std::vector<std::string>&),
+                (override));
 };
 
 }  // namespace watchdog
diff --git a/cpp/watchdog/server/tests/MockPackageInfoResolver.h b/cpp/watchdog/server/tests/MockPackageInfoResolver.h
index e3da3b6..34f4c60 100644
--- a/cpp/watchdog/server/tests/MockPackageInfoResolver.h
+++ b/cpp/watchdog/server/tests/MockPackageInfoResolver.h
@@ -33,8 +33,7 @@
 public:
     MockPackageInfoResolver() {}
     MOCK_METHOD(android::base::Result<void>, initWatchdogServiceHelper,
-                (const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper),
-                (override));
+                (const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper), (override));
     MOCK_METHOD((std::unordered_map<uid_t, std::string>), getPackageNamesForUids,
                 (const std::vector<uid_t>& uids), (override));
     MOCK_METHOD((std::unordered_map<uid_t, android::automotive::watchdog::internal::PackageInfo>),
diff --git a/cpp/watchdog/server/tests/MockWatchdogProcessService.h b/cpp/watchdog/server/tests/MockWatchdogProcessService.h
index b720d91..ac78b45 100644
--- a/cpp/watchdog/server/tests/MockWatchdogProcessService.h
+++ b/cpp/watchdog/server/tests/MockWatchdogProcessService.h
@@ -43,7 +43,7 @@
     MOCK_METHOD(android::base::Result<void>, dump, (int fd, const Vector<android::String16>& args),
                 (override));
     MOCK_METHOD(android::base::Result<void>, registerWatchdogServiceHelper,
-                (const android::sp<IWatchdogServiceHelperInterface>& helper), (override));
+                (const android::sp<IWatchdogServiceHelper>& helper), (override));
 
     MOCK_METHOD(android::binder::Status, registerClient,
                 (const sp<ICarWatchdogClient>& client, TimeoutLength timeout), (override));
diff --git a/cpp/watchdog/server/tests/MockWatchdogServiceHelper.h b/cpp/watchdog/server/tests/MockWatchdogServiceHelper.h
index 847c561..3d71345 100644
--- a/cpp/watchdog/server/tests/MockWatchdogServiceHelper.h
+++ b/cpp/watchdog/server/tests/MockWatchdogServiceHelper.h
@@ -32,7 +32,7 @@
 namespace automotive {
 namespace watchdog {
 
-class MockWatchdogServiceHelper : public IWatchdogServiceHelperInterface {
+class MockWatchdogServiceHelper : public IWatchdogServiceHelper {
 public:
     MockWatchdogServiceHelper() {}
     ~MockWatchdogServiceHelper() {}
@@ -59,7 +59,8 @@
             android::binder::Status, latestIoOveruseStats,
             (const std::vector<android::automotive::watchdog::internal::PackageIoOveruseStats>&),
             (override));
-
+    MOCK_METHOD(android::binder::Status, resetResourceOveruseStats,
+                (const std::vector<std::string>&), (override));
     MOCK_METHOD(void, terminate, (), (override));
 };
 
diff --git a/cpp/watchdog/server/tests/WatchdogBinderMediatorTest.cpp b/cpp/watchdog/server/tests/WatchdogBinderMediatorTest.cpp
index 0cc3510..64f9c07 100644
--- a/cpp/watchdog/server/tests/WatchdogBinderMediatorTest.cpp
+++ b/cpp/watchdog/server/tests/WatchdogBinderMediatorTest.cpp
@@ -40,8 +40,8 @@
 using ::android::binder::Status;
 using ::testing::_;
 using ::testing::DoAll;
-using ::testing::NiceMock;
 using ::testing::Return;
+using ::testing::SaveArg;
 using ::testing::SetArgPointee;
 using ::testing::UnorderedElementsAreArray;
 
@@ -172,13 +172,13 @@
     EXPECT_EQ(mWatchdogBinderMediator->mWatchdogInternalHandler, nullptr);
 }
 
-TEST_F(WatchdogBinderMediatorTest, TestHandlesEmptyDumpArgs) {
+TEST_F(WatchdogBinderMediatorTest, TestDumpWithEmptyArgs) {
     EXPECT_CALL(*mMockWatchdogProcessService, dump(-1, _)).WillOnce(Return(Result<void>()));
     EXPECT_CALL(*mMockWatchdogPerfService, onDump(-1)).WillOnce(Return(Result<void>()));
     mWatchdogBinderMediator->dump(-1, Vector<String16>());
 }
 
-TEST_F(WatchdogBinderMediatorTest, TestHandlesStartCustomPerfCollection) {
+TEST_F(WatchdogBinderMediatorTest, TestDumpWithStartCustomPerfCollection) {
     EXPECT_CALL(*mMockWatchdogPerfService, onCustomCollection(-1, _))
             .WillOnce(Return(Result<void>()));
 
@@ -187,7 +187,7 @@
     ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), OK);
 }
 
-TEST_F(WatchdogBinderMediatorTest, TestHandlesStopCustomPerfCollection) {
+TEST_F(WatchdogBinderMediatorTest, TestDumpWithStopCustomPerfCollection) {
     EXPECT_CALL(*mMockWatchdogPerfService, onCustomCollection(-1, _))
             .WillOnce(Return(Result<void>()));
 
@@ -196,10 +196,36 @@
     ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), OK);
 }
 
-TEST_F(WatchdogBinderMediatorTest, TestErrorOnInvalidDumpArgs) {
+TEST_F(WatchdogBinderMediatorTest, TestDumpWithResetResourceOveruseStats) {
+    std::vector<std::string> actualPackages;
+    EXPECT_CALL(*mMockIoOveruseMonitor, resetIoOveruseStats(_))
+            .WillOnce(DoAll(SaveArg<0>(&actualPackages), Return(Result<void>())));
+
+    Vector<String16> args;
+    args.push_back(String16(kResetResourceOveruseStatsFlag));
+    args.push_back(String16("packageA,packageB"));
+    ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), OK);
+    ASSERT_EQ(actualPackages, std::vector<std::string>({"packageA", "packageB"}));
+}
+
+TEST_F(WatchdogBinderMediatorTest, TestFailsDumpWithInvalidResetResourceOveruseStatsArg) {
+    EXPECT_CALL(*mMockIoOveruseMonitor, resetIoOveruseStats(_)).Times(0);
+
+    Vector<String16> args;
+    args.push_back(String16(kResetResourceOveruseStatsFlag));
+    args.push_back(String16(""));
+    ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), BAD_VALUE);
+}
+
+TEST_F(WatchdogBinderMediatorTest, TestDumpWithInvalidDumpArgs) {
     Vector<String16> args;
     args.push_back(String16("--invalid_option"));
-    ASSERT_EQ(mWatchdogBinderMediator->dump(-1, args), OK) << "Error returned on invalid args";
+    int nullFd = open("/dev/null", O_RDONLY);
+    EXPECT_CALL(*mMockWatchdogProcessService, dump(nullFd, _)).WillOnce(Return(Result<void>()));
+    EXPECT_CALL(*mMockWatchdogPerfService, onDump(nullFd)).WillOnce(Return(Result<void>()));
+
+    EXPECT_EQ(mWatchdogBinderMediator->dump(nullFd, args), OK) << "Error returned on invalid args";
+    close(nullFd);
 }
 
 TEST_F(WatchdogBinderMediatorTest, TestRegisterClient) {
diff --git a/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp b/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
index f5dd7dc..40d6389 100644
--- a/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
+++ b/cpp/watchdog/server/tests/WatchdogInternalHandlerTest.cpp
@@ -42,7 +42,6 @@
 
 namespace aawi = ::android::automotive::watchdog::internal;
 
-using aawi::ComponentType;
 using aawi::ICarWatchdogServiceForSystem;
 using aawi::ICarWatchdogServiceForSystemDefault;
 using aawi::PackageResourceOveruseAction;
@@ -59,10 +58,9 @@
 
 class MockWatchdogBinderMediator : public WatchdogBinderMediator {
 public:
-    MockWatchdogBinderMediator(
-            const android::sp<WatchdogProcessService>& watchdogProcessService,
-            const android::sp<WatchdogPerfService>& watchdogPerfService,
-            const android::sp<IWatchdogServiceHelperInterface>& watchdogServiceHelper) :
+    MockWatchdogBinderMediator(const android::sp<WatchdogProcessService>& watchdogProcessService,
+                               const android::sp<WatchdogPerfService>& watchdogPerfService,
+                               const android::sp<IWatchdogServiceHelper>& watchdogServiceHelper) :
           WatchdogBinderMediator(watchdogProcessService, watchdogPerfService, watchdogServiceHelper,
                                  [](const char*, const android::sp<android::IBinder>&)
                                          -> Result<void> { return Result<void>{}; }) {}
diff --git a/cpp/watchdog/server/tests/WatchdogServiceHelperTest.cpp b/cpp/watchdog/server/tests/WatchdogServiceHelperTest.cpp
index 17edadf..99b65df 100644
--- a/cpp/watchdog/server/tests/WatchdogServiceHelperTest.cpp
+++ b/cpp/watchdog/server/tests/WatchdogServiceHelperTest.cpp
@@ -32,11 +32,9 @@
 using aawi::ApplicationCategoryType;
 using aawi::ComponentType;
 using aawi::ICarWatchdogServiceForSystem;
-using aawi::ICarWatchdogServiceForSystemDefault;
 using aawi::PackageInfo;
 using aawi::PackageIoOveruseStats;
 using aawi::UidType;
-using ::android::BBinder;
 using ::android::IBinder;
 using ::android::RefBase;
 using ::android::sp;
@@ -47,7 +45,6 @@
 using ::testing::DoAll;
 using ::testing::IsEmpty;
 using ::testing::Return;
-using ::testing::SaveArg;
 using ::testing::SetArgPointee;
 using ::testing::UnorderedElementsAreArray;
 
@@ -152,7 +149,7 @@
     sp<MockWatchdogProcessService> mockWatchdogProcessService(new MockWatchdogProcessService());
 
     EXPECT_CALL(*mockWatchdogProcessService, registerWatchdogServiceHelper(_))
-            .WillOnce([](const sp<IWatchdogServiceHelperInterface>&) -> Result<void> {
+            .WillOnce([](const sp<IWatchdogServiceHelper>&) -> Result<void> {
                 return Error() << "Failed to register";
             });
 
@@ -388,21 +385,19 @@
     stats.ioOveruseStats.totalOveruses = 10;
     stats.shouldNotify = true;
     std::vector<PackageIoOveruseStats> expectedIoOveruseStats = {stats};
-    std::vector<PackageIoOveruseStats> actualOveruseStats;
 
     registerCarWatchdogService();
 
     EXPECT_CALL(*mMockCarWatchdogServiceForSystem, latestIoOveruseStats(expectedIoOveruseStats))
-            .WillOnce(DoAll(SaveArg<0>(&actualOveruseStats), Return(Status::ok())));
+            .WillOnce(Return(Status::ok()));
 
     Status status = mWatchdogServiceHelper->latestIoOveruseStats(expectedIoOveruseStats);
 
     ASSERT_TRUE(status.isOk()) << status;
-    EXPECT_THAT(actualOveruseStats, UnorderedElementsAreArray(expectedIoOveruseStats));
 }
 
 TEST_F(WatchdogServiceHelperTest,
-       TestErrorsOnLatetstIoOveruseStatsWithNoCarWatchdogServiceRegistered) {
+       TestErrorsOnLatestIoOveruseStatsWithNoCarWatchdogServiceRegistered) {
     EXPECT_CALL(*mMockCarWatchdogServiceForSystem, latestIoOveruseStats(_)).Times(0);
 
     Status status = mWatchdogServiceHelper->latestIoOveruseStats({});
@@ -412,7 +407,7 @@
 }
 
 TEST_F(WatchdogServiceHelperTest,
-       TestErrorsOnLatetstIoOveruseStatsWithErrorStatusFromCarWatchdogService) {
+       TestErrorsOnLatestIoOveruseStatsWithErrorStatusFromCarWatchdogService) {
     registerCarWatchdogService();
 
     EXPECT_CALL(*mMockCarWatchdogServiceForSystem, latestIoOveruseStats(_))
@@ -424,6 +419,41 @@
                                    "service API returns error";
 }
 
+TEST_F(WatchdogServiceHelperTest, TestResetResourceOveruseStats) {
+    registerCarWatchdogService();
+
+    std::vector<std::string> packageNames = {"system.daemon"};
+    EXPECT_CALL(*mMockCarWatchdogServiceForSystem, resetResourceOveruseStats(packageNames))
+            .WillOnce(Return(Status::ok()));
+
+    Status status = mWatchdogServiceHelper->resetResourceOveruseStats(packageNames);
+
+    ASSERT_TRUE(status.isOk()) << status;
+}
+
+TEST_F(WatchdogServiceHelperTest,
+       TestErrorsOnResetResourceOveruseStatsWithNoCarWatchdogServiceRegistered) {
+    EXPECT_CALL(*mMockCarWatchdogServiceForSystem, resetResourceOveruseStats(_)).Times(0);
+
+    Status status = mWatchdogServiceHelper->resetResourceOveruseStats({});
+
+    ASSERT_FALSE(status.isOk()) << "resetResourceOveruseStats should fail when no "
+                                   "car watchdog service registered with the helper";
+}
+
+TEST_F(WatchdogServiceHelperTest,
+       TestErrorsOnResetResourceOveruseStatsWithErrorStatusFromCarWatchdogService) {
+    registerCarWatchdogService();
+
+    EXPECT_CALL(*mMockCarWatchdogServiceForSystem, resetResourceOveruseStats(_))
+            .WillOnce(Return(Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "Illegal state")));
+
+    Status status = mWatchdogServiceHelper->resetResourceOveruseStats({});
+
+    ASSERT_FALSE(status.isOk()) << "resetResourceOveruseStats should fail when car watchdog "
+                                   "service API returns error";
+}
+
 }  // namespace watchdog
 }  // namespace automotive
 }  // namespace android
diff --git a/service/src/com/android/car/watchdog/CarWatchdogService.java b/service/src/com/android/car/watchdog/CarWatchdogService.java
index 0b26e0a..b039c14 100644
--- a/service/src/com/android/car/watchdog/CarWatchdogService.java
+++ b/service/src/com/android/car/watchdog/CarWatchdogService.java
@@ -44,6 +44,7 @@
 import android.os.RemoteException;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.util.ArraySet;
 import android.util.IndentingPrintWriter;
 
 import com.android.car.CarLocalServices;
@@ -434,5 +435,19 @@
             }
             service.mWatchdogPerfHandler.latestIoOveruseStats(packageIoOveruseStats);
         }
+
+        @Override
+        public void resetResourceOveruseStats(List<String> packageNames) {
+            if (packageNames.isEmpty()) {
+                Slogf.w(TAG, "Provided an empty package name to reset resource overuse stats");
+                return;
+            }
+            CarWatchdogService service = mService.get();
+            if (service == null) {
+                Slogf.w(TAG, "CarWatchdogService is not available");
+                return;
+            }
+            service.mWatchdogPerfHandler.resetResourceOveruseStats(new ArraySet<>(packageNames));
+        }
     }
 }
diff --git a/service/src/com/android/car/watchdog/WatchdogPerfHandler.java b/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
index 80dcb82..8ed2301 100644
--- a/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
+++ b/service/src/com/android/car/watchdog/WatchdogPerfHandler.java
@@ -596,6 +596,21 @@
         }
     }
 
+    /** Resets the resource overuse stats for the given package. */
+    public void resetResourceOveruseStats(Set<String> packageNames) {
+        synchronized (mLock) {
+            for (PackageResourceUsage usage : mUsageByUserPackage.values()) {
+                if (packageNames.contains(usage.packageName)) {
+                    usage.resetStats();
+                    /*
+                     * TODO(b/185287136): When the stats are persisted in local DB, reset the stats
+                     *  for this package from local DB.
+                     */
+                }
+            }
+        }
+    }
+
     private void notifyResourceOveruseStatsLocked(int uid,
             ResourceOveruseStats resourceOveruseStats) {
         String packageName = resourceOveruseStats.getPackageName();
@@ -656,7 +671,7 @@
                 }
             }
             /* TODO(b/170741935): Stash the old usage into SQLite DB storage. */
-            usage.ioUsage.clear();
+            usage.resetStats();
         }
         if (CarWatchdogService.DEBUG) {
             Slogf.d(CarWatchdogService.TAG, "Handled date change successfully");
@@ -1110,6 +1125,10 @@
             }
             return mKillableState;
         }
+
+        public void resetStats() {
+            ioUsage.resetStats();
+        }
     }
 
     private static final class PackageIoUsage {
@@ -1154,7 +1173,7 @@
                     || remaining.garageModeBytes == 0;
         }
 
-        public void clear() {
+        public void resetStats() {
             mIoOveruseStats = null;
             mForgivenWriteBytes = null;
             mTotalTimesKilled = 0;
diff --git a/tests/BugReportApp/AndroidManifest.xml b/tests/BugReportApp/AndroidManifest.xml
index 7137bbc..a13c4c9 100644
--- a/tests/BugReportApp/AndroidManifest.xml
+++ b/tests/BugReportApp/AndroidManifest.xml
@@ -20,6 +20,9 @@
           android:versionName="1.7.2">
 
     <uses-permission android:name="android.car.permission.CAR_DRIVING_STATE"/>
+    <!-- Allow closing HVAC dialog when showing bugreport activity, used by
+         ACTION_CLOSE_SYSTEM_DIALOGS. -->
+    <uses-permission android:name="android.car.permission.CONTROL_CAR_CLIMATE"/>
     <uses-permission android:name="android.permission.INTERNET"/>
     <uses-permission android:name="android.permission.READ_LOGS"/>
     <uses-permission android:name="android.permission.READ_FRAME_BUFFER"/>
diff --git a/tests/NetworkPreferenceApp/src/com/google/android/car/networking/preferenceupdater/fragments/ManagerFragment.java b/tests/NetworkPreferenceApp/src/com/google/android/car/networking/preferenceupdater/fragments/ManagerFragment.java
index 76a6299..a6f6e6b 100644
--- a/tests/NetworkPreferenceApp/src/com/google/android/car/networking/preferenceupdater/fragments/ManagerFragment.java
+++ b/tests/NetworkPreferenceApp/src/com/google/android/car/networking/preferenceupdater/fragments/ManagerFragment.java
@@ -270,6 +270,7 @@
         mOEMPaidWifiSSIDsEditText.setText(Utils.toString(mPersonalStorage.getOemPaidWifiSsids()));
         mOEMPrivateWifiSSIDsEditText.setText(
                 Utils.toString(mPersonalStorage.getOemPrivateWifiSsids()));
+        updatePansPolicyInEffectStatus(false);
     }
 
     private String getFromStorage(int type) {
diff --git a/tests/android_car_api_test/src/android/car/apitest/CarApiTestBase.java b/tests/android_car_api_test/src/android/car/apitest/CarApiTestBase.java
index 78ce04c..1ff7911 100644
--- a/tests/android_car_api_test/src/android/car/apitest/CarApiTestBase.java
+++ b/tests/android_car_api_test/src/android/car/apitest/CarApiTestBase.java
@@ -140,7 +140,7 @@
         PowerManager powerManager = sContext.getSystemService(PowerManager.class);
         runShellCommand("cmd car_service suspend");
         // Check for suspend success
-        waitUntil("Suspend is not successful",
+        waitUntil("screen is still on after suspend",
                 SUSPEND_TIMEOUT_MS, () -> !powerManager.isScreenOn());
 
         // Force turn off garage mode
diff --git a/tests/carservice_unit_test/src/android/car/watchdoglib/CarWatchdogDaemonHelperTest.java b/tests/carservice_unit_test/src/android/car/watchdoglib/CarWatchdogDaemonHelperTest.java
index 92dfb9a..c644f77 100644
--- a/tests/carservice_unit_test/src/android/car/watchdoglib/CarWatchdogDaemonHelperTest.java
+++ b/tests/carservice_unit_test/src/android/car/watchdoglib/CarWatchdogDaemonHelperTest.java
@@ -263,5 +263,8 @@
 
         @Override
         public void latestIoOveruseStats(List<PackageIoOveruseStats> ioOveruseStats) {}
+
+        @Override
+        public void resetResourceOveruseStats(List<String> packageNames) {}
     }
 }
diff --git a/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java b/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
index cdb3452..32677d2 100644
--- a/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/watchdog/CarWatchdogServiceUnitTest.java
@@ -151,7 +151,7 @@
         mWatchdogServiceForSystemImpl.checkIfAlive(123456, TIMEOUT_CRITICAL);
         verify(mMockCarWatchdogDaemon,
                 timeout(MAX_WAIT_TIME_MS)).tellCarWatchdogServiceAlive(
-                        eq(mWatchdogServiceForSystemImpl), any(int[].class), eq(123456));
+                eq(mWatchdogServiceForSystemImpl), any(int[].class), eq(123456));
     }
 
     @Test
@@ -199,12 +199,13 @@
 
         List<PackageIoOveruseStats> packageIoOveruseStats = new ArrayList<>(
                 Collections.singletonList(
-                    constructPackageIoOveruseStats(
-                            Binder.getCallingUid(), /* shouldNotify= */false,
-                            constructInternalIoOveruseStats(/* killableOnOveruse= */false,
-                                    /* remainingWriteBytes= */constructPerStateBytes(20, 20, 20),
-                                    /* writtenBytes= */constructPerStateBytes(100, 200, 300),
-                                    /* totalOveruses= */2)))
+                        constructPackageIoOveruseStats(
+                                Binder.getCallingUid(), /* shouldNotify= */false,
+                                constructInternalIoOveruseStats(/* killableOnOveruse= */false,
+                                        /* remainingWriteBytes= */
+                                        constructPerStateBytes(20, 20, 20),
+                                        /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                        /* totalOveruses= */2)))
         );
         mWatchdogServiceForSystemImpl.latestIoOveruseStats(packageIoOveruseStats);
 
@@ -371,7 +372,7 @@
         assertThrows(NullPointerException.class,
                 () -> mCarWatchdogService.getResourceOveruseStatsForUserPackage("some.package",
                         /* userHandle= */null, CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
-                CarWatchdogManager.STATS_PERIOD_CURRENT_DAY));
+                        CarWatchdogManager.STATS_PERIOD_CURRENT_DAY));
 
         assertThrows(IllegalArgumentException.class,
                 () -> mCarWatchdogService.getResourceOveruseStatsForUserPackage("some.package",
@@ -499,10 +500,10 @@
 
         PackageKillableStateSubject.assertThat(
                 mCarWatchdogService.getPackageKillableStatesAsUser(userHandle)).containsExactly(
-                        new PackageKillableState("third_party_package", 11,
-                                PackageKillableState.KILLABLE_STATE_YES),
-                        new PackageKillableState("vendor_package.critical", 11,
-                                PackageKillableState.KILLABLE_STATE_NEVER));
+                new PackageKillableState("third_party_package", 11,
+                        PackageKillableState.KILLABLE_STATE_YES),
+                new PackageKillableState("vendor_package.critical", 11,
+                        PackageKillableState.KILLABLE_STATE_NEVER));
 
         mCarWatchdogService.setKillablePackageAsUser("third_party_package", userHandle,
                 /* isKillable= */ false);
@@ -528,7 +529,7 @@
         mCarWatchdogService.setKillablePackageAsUser("third_party_package", userHandle,
                 /* isKillable= */ true);
         mCarWatchdogService.setKillablePackageAsUser("vendor_package.critical",
-                        userHandle, /* isKillable= */ true);
+                userHandle, /* isKillable= */ true);
 
         PackageKillableStateSubject.assertThat(
                 mCarWatchdogService.getPackageKillableStatesAsUser(userHandle)).containsExactly(
@@ -607,7 +608,7 @@
         mCarWatchdogService.setKillablePackageAsUser("third_party_package", UserHandle.ALL,
                 /* isKillable= */ true);
         mCarWatchdogService.setKillablePackageAsUser("vendor_package.critical",
-                        UserHandle.ALL, /* isKillable= */ true);
+                UserHandle.ALL, /* isKillable= */ true);
 
         PackageKillableStateSubject.assertThat(
                 mCarWatchdogService.getPackageKillableStatesAsUser(UserHandle.ALL)).containsExactly(
@@ -723,7 +724,7 @@
     public void testFailsSetResourceOveruseConfigurationsOnDuplicateComponents() throws Exception {
         ResourceOveruseConfiguration config =
                 sampleResourceOveruseConfigurationBuilder(ComponentType.SYSTEM,
-                sampleIoOveruseConfigurationBuilder(ComponentType.SYSTEM).build()).build();
+                        sampleIoOveruseConfigurationBuilder(ComponentType.SYSTEM).build()).build();
         List<ResourceOveruseConfiguration> resourceOveruseConfigs = new ArrayList<>(Arrays.asList(
                 config, config));
         assertThrows(IllegalArgumentException.class,
@@ -859,9 +860,9 @@
 
         List<PackageResourceOveruseAction> expectedActions = new ArrayList<>(Arrays.asList(
                 constructPackageResourceOveruseAction(packageNamesByUid.get(criticalSysPkgUid),
-                        criticalSysPkgUid, new int[]{ ResourceType.IO }, NOT_KILLED),
+                        criticalSysPkgUid, new int[]{ResourceType.IO}, NOT_KILLED),
                 constructPackageResourceOveruseAction(packageNamesByUid.get(thirdPartyPkgUid),
-                        thirdPartyPkgUid, new int[]{ ResourceType.IO }, KILLED)));
+                        thirdPartyPkgUid, new int[]{ResourceType.IO}, KILLED)));
         verifyActionsTakenOnResourceOveruse(expectedActions);
     }
 
@@ -879,6 +880,44 @@
     }
 
     @Test
+    public void testResetResourceOveruseStats() throws Exception {
+        SparseArray<String> packageNamesByUid = new SparseArray<>();
+        packageNamesByUid.put(Binder.getCallingUid(), mMockContext.getPackageName());
+        packageNamesByUid.put(1101278, "vendor_package.critical");
+        injectUidToPackageNameMapping(packageNamesByUid);
+
+        List<PackageIoOveruseStats> packageIoOveruseStats = Arrays.asList(
+                constructPackageIoOveruseStats(
+                        Binder.getCallingUid(), /* shouldNotify= */false,
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */false,
+                                /* remainingWriteBytes= */constructPerStateBytes(20, 20, 20),
+                                /* writtenBytes= */constructPerStateBytes(100, 200, 300),
+                                /* totalOveruses= */2)),
+                constructPackageIoOveruseStats(
+                        1101278, /* shouldNotify= */false,
+                        constructInternalIoOveruseStats(/* killableOnOveruse= */false,
+                                /* remainingWriteBytes= */constructPerStateBytes(120, 220, 230),
+                                /* writtenBytes= */constructPerStateBytes(3100, 5200, 6300),
+                                /* totalOveruses= */3)));
+        mWatchdogServiceForSystemImpl.latestIoOveruseStats(packageIoOveruseStats);
+
+        mWatchdogServiceForSystemImpl.resetResourceOveruseStats(
+                Collections.singletonList(mMockContext.getPackageName()));
+
+        ResourceOveruseStats actualStats = mCarWatchdogService.getResourceOveruseStats(
+                CarWatchdogManager.FLAG_RESOURCE_OVERUSE_IO,
+                CarWatchdogManager.STATS_PERIOD_CURRENT_DAY);
+
+        ResourceOveruseStats expectedStats = new ResourceOveruseStats.Builder(
+                mMockContext.getPackageName(),
+                UserHandle.getUserHandleForUid(Binder.getCallingUid())).build();
+
+        assertWithMessage("Expected: " + expectedStats.toString() + "\nActual: "
+                + actualStats.toString())
+                .that(ResourceOveruseStatsSubject.isEquals(actualStats, expectedStats)).isTrue();
+    }
+
+    @Test
     public void testGetPackageInfosForUids() throws Exception {
         int[] uids = new int[]{6001, 6050, 5100, 110035, 120056, 120078, 1345678};
         List<PackageInfo> expectedPackageInfos = new ArrayList<>(Arrays.asList(
@@ -898,7 +937,7 @@
                         ApplicationCategoryType.OTHERS),
                 constructPackageInfo("shared:third_party.package", 120078,
                         new ArrayList<>(Arrays.asList("third_party.package.I")),
-                        UidType.APPLICATION,  ComponentType.THIRD_PARTY,
+                        UidType.APPLICATION, ComponentType.THIRD_PARTY,
                         ApplicationCategoryType.OTHERS),
                 constructPackageInfo("vendor.package.J", 1345678, new ArrayList<>(),
                         UidType.APPLICATION, ComponentType.VENDOR,
@@ -1320,7 +1359,8 @@
         }
 
         @Override
-        public void onPrepareProcessTermination() {}
+        public void onPrepareProcessTermination() {
+        }
 
         public int getLastSessionId() {
             return mLastSessionId;
@@ -1359,7 +1399,7 @@
                             .getOrDefault(packageName, /* defaultValue= */ null);
                     if (applicationInfo == null) {
                         throw new PackageManager.NameNotFoundException(
-                            "Package " + packageName + " not found exception");
+                                "Package " + packageName + " not found exception");
                     }
                     return applicationInfo;
                 });
@@ -1399,8 +1439,8 @@
             return builder.append("Null package info\n");
         }
         builder.append("Package name: '").append(packageInfo.packageIdentifier.name)
-            .append("', UID: ").append(packageInfo.packageIdentifier.uid).append('\n')
-            .append("Owned packages: ");
+                .append("', UID: ").append(packageInfo.packageIdentifier.uid).append('\n')
+                .append("Owned packages: ");
         if (packageInfo.sharedUidPackages != null) {
             for (int i = 0; i < packageInfo.sharedUidPackages.size(); ++i) {
                 builder.append('\'').append(packageInfo.sharedUidPackages.get(i)).append('\'');
@@ -1413,7 +1453,8 @@
             builder.append("Null");
         }
         builder.append("Component type: ").append(packageInfo.componentType).append('\n')
-            .append("Application category type: ").append(packageInfo.appCategoryType).append('\n');
+                .append("Application category type: ").append(packageInfo.appCategoryType).append(
+                '\n');
 
         return builder;
     }