Statsd: Add watchdog rollback to experiment ids
Stores experiment ids to disk for watchdog rollback initiate/success
events as discussed.
Test: gts in topic
Bug: 131768455
Change-Id: I32768fe5c5c21c43811e25d8f87faae0c8d82c1f
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 8191d37..bbd3dca 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1264,7 +1264,7 @@
// This method only sends data, it does not receive it.
pid_t pid = IPCThreadState::self()->getCallingPid();
uid_t uid = IPCThreadState::self()->getCallingUid();
- // Root, system, and shell always have access
+ // Root, system, and shell always have access
if (uid != AID_ROOT && uid != AID_SYSTEM && uid != AID_SHELL) {
// Caller must be granted these permissions
if (!checkCallingPermission(String16(kPermissionDump))) {
@@ -1349,6 +1349,64 @@
return Status::ok();
}
+Status StatsService::sendWatchdogRollbackOccurredAtom(const int32_t rollbackTypeIn,
+ const android::String16& packageNameIn,
+ const int64_t packageVersionCodeIn) {
+ // Note: We skip the usage stats op check here since we do not have a package name.
+ // This is ok since we are overloading the usage_stats permission.
+ // This method only sends data, it does not receive it.
+ pid_t pid = IPCThreadState::self()->getCallingPid();
+ uid_t uid = IPCThreadState::self()->getCallingUid();
+ // Root, system, and shell always have access
+ if (uid != AID_ROOT && uid != AID_SYSTEM && uid != AID_SHELL) {
+ // Caller must be granted these permissions
+ if (!checkCallingPermission(String16(kPermissionDump))) {
+ return exception(binder::Status::EX_SECURITY,
+ StringPrintf("UID %d / PID %d lacks permission %s", uid, pid,
+ kPermissionDump));
+ }
+ if (!checkCallingPermission(String16(kPermissionUsage))) {
+ return exception(binder::Status::EX_SECURITY,
+ StringPrintf("UID %d / PID %d lacks permission %s", uid, pid,
+ kPermissionUsage));
+ }
+ }
+
+ android::util::stats_write(android::util::WATCHDOG_ROLLBACK_OCCURRED,
+ rollbackTypeIn, String8(packageNameIn).string(), packageVersionCodeIn);
+
+ // Fast return to save disk read.
+ if (rollbackTypeIn != android::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS
+ && rollbackTypeIn !=
+ android::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE) {
+ return Status::ok();
+ }
+
+ bool readTrainInfoSuccess = false;
+ InstallTrainInfo trainInfoOnDisk;
+ readTrainInfoSuccess = StorageManager::readTrainInfo(trainInfoOnDisk);
+
+ if (!readTrainInfoSuccess) {
+ return Status::ok();
+ }
+ std::vector<int64_t> experimentIds = trainInfoOnDisk.experimentIds;
+ if (experimentIds.empty()) {
+ return Status::ok();
+ }
+ switch (rollbackTypeIn) {
+ case android::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE:
+ experimentIds.push_back(experimentIds[0] + 4);
+ break;
+ case android::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS:
+ experimentIds.push_back(experimentIds[0] + 5);
+ break;
+ }
+ StorageManager::writeTrainInfo(trainInfoOnDisk.trainVersionCode, trainInfoOnDisk.trainName,
+ trainInfoOnDisk.status, experimentIds);
+ return Status::ok();
+}
+
+
Status StatsService::getRegisteredExperimentIds(std::vector<int64_t>* experimentIdsOut) {
uid_t uid = IPCThreadState::self()->getCallingUid();
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index a4e6d7f..8d8514f 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -196,6 +196,14 @@
const std::vector<int64_t>& experimentIdsIn) override;
/**
+ * Binder call to log WatchdogRollbackOccurred atom.
+ */
+ virtual Status sendWatchdogRollbackOccurredAtom(
+ const int32_t rollbackTypeIn,
+ const android::String16& packageNameIn,
+ const int64_t packageVersionCodeIn) override;
+
+ /**
* Binder call to get registered experiment IDs.
*/
virtual Status getRegisteredExperimentIds(std::vector<int64_t>* expIdsOut);
diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl
index 311c86d..a596fdc 100644
--- a/core/java/android/os/IStatsManager.aidl
+++ b/core/java/android/os/IStatsManager.aidl
@@ -219,6 +219,12 @@
in int options, in int state, in long[] experimentId);
/**
+ * Logs an event for watchdog rollbacks.
+ */
+ oneway void sendWatchdogRollbackOccurredAtom(in int rollbackType, in String packageName,
+ in long packageVersionCode);
+
+ /**
* Returns the most recently registered experiment IDs.
*/
long[] getRegisteredExperimentIds();
diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java
index cfc092c..f7077bb 100644
--- a/core/java/android/util/StatsLog.java
+++ b/core/java/android/util/StatsLog.java
@@ -23,7 +23,6 @@
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.app.IActivityManager;
import android.content.Context;
import android.os.IStatsManager;
import android.os.RemoteException;
@@ -159,10 +158,6 @@
}
return false;
}
- int userId = IActivityManager.Stub.asInterface(
- ServiceManager.getService("activity"))
- .getCurrentUser()
- .id;
service.sendBinaryPushStateChangedAtom(
trainName, trainVersionCode, options, state, experimentIds);
return true;
@@ -178,6 +173,46 @@
}
}
+ /**
+ * Logs an event for watchdog rollbacks.
+ *
+ * @param rollbackType state of the rollback.
+ * @param packageName package name being rolled back.
+ * @param packageVersionCode version of the package being rolled back.
+ *
+ * @return True if the log request was sent to statsd.
+ *
+ * @hide
+ */
+ @RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
+ public static boolean logWatchdogRollbackOccurred(int rollbackType, String packageName,
+ long packageVersionCode) {
+ synchronized (sLogLock) {
+ try {
+ IStatsManager service = getIStatsManagerLocked();
+ if (service == null) {
+ if (DEBUG) {
+ Slog.d(TAG, "Failed to find statsd when logging event");
+ }
+ return false;
+ }
+
+ service.sendWatchdogRollbackOccurredAtom(rollbackType, packageName,
+ packageVersionCode);
+ return true;
+ } catch (RemoteException e) {
+ sService = null;
+ if (DEBUG) {
+ Slog.d(TAG,
+ "Failed to connect to StatsCompanionService when logging "
+ + "WatchdogRollbackOccurred");
+ }
+ return false;
+ }
+ }
+ }
+
+
private static IStatsManager getIStatsManagerLocked() throws RemoteException {
if (sService != null) {
return sService;
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index bcef66c..9272e96 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -338,8 +338,8 @@
private static void logEvent(@Nullable VersionedPackage moduleMetadataPackage, int type) {
Slog.i(TAG, "Watchdog event occurred of type: " + type);
if (moduleMetadataPackage != null) {
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED, type,
- moduleMetadataPackage.getPackageName(), moduleMetadataPackage.getVersionCode());
+ StatsLog.logWatchdogRollbackOccurred(type, moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
}
}