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;
}