summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGavin Corkery <gavincorkery@google.com>2019-12-20 08:02:11 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-12-20 08:02:11 +0000
commitcb6ad6dc8e3ae33a6d82dc4a92b4b32485a1e6be (patch)
tree714981f47a9a46510a810433e09c9fb0015e7437
parentcd0dc3caafb1e3c2fe15c1799543662cf27e0585 (diff)
parent231b3d8f6032d5451b9fb8dc94bcbfacaef9af13 (diff)
downloadframeworks_base-cb6ad6dc8e3ae33a6d82dc4a92b4b32485a1e6be.tar.gz
frameworks_base-cb6ad6dc8e3ae33a6d82dc4a92b4b32485a1e6be.tar.bz2
frameworks_base-cb6ad6dc8e3ae33a6d82dc4a92b4b32485a1e6be.zip
Merge changes from topic "cp-log-watchdog" into qt-qpr1-dev
* changes: Log native crashing process Log watchdog-initiated rollback reason Add package failure flags to Package Watchdog
-rw-r--r--cmds/statsd/src/StatsService.cpp8
-rw-r--r--cmds/statsd/src/StatsService.h4
-rw-r--r--cmds/statsd/src/atoms.proto13
-rw-r--r--core/java/android/os/IStatsManager.aidl2
-rw-r--r--core/java/android/util/StatsLog.java6
-rw-r--r--services/core/java/com/android/server/PackageWatchdog.java31
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java6
-rw-r--r--services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java64
-rw-r--r--tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java73
9 files changed, 172 insertions, 35 deletions
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index b665a8b99fb..64b7aae0161 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1394,7 +1394,10 @@ Status StatsService::sendBinaryPushStateChangedAtom(const android::String16& tra
Status StatsService::sendWatchdogRollbackOccurredAtom(const int32_t rollbackTypeIn,
const android::String16& packageNameIn,
- const int64_t packageVersionCodeIn) {
+ const int64_t packageVersionCodeIn,
+ const int32_t rollbackReasonIn,
+ const android::String16&
+ failingPackageNameIn) {
// 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.
@@ -1416,7 +1419,8 @@ Status StatsService::sendWatchdogRollbackOccurredAtom(const int32_t rollbackType
}
android::util::stats_write(android::util::WATCHDOG_ROLLBACK_OCCURRED,
- rollbackTypeIn, String8(packageNameIn).string(), packageVersionCodeIn);
+ rollbackTypeIn, String8(packageNameIn).string(), packageVersionCodeIn,
+ rollbackReasonIn, String8(failingPackageNameIn).string());
// Fast return to save disk read.
if (rollbackTypeIn != android::util::WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index 94909487193..5f1335efc2e 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -200,7 +200,9 @@ public:
virtual Status sendWatchdogRollbackOccurredAtom(
const int32_t rollbackTypeIn,
const android::String16& packageNameIn,
- const int64_t packageVersionCodeIn) override;
+ const int64_t packageVersionCodeIn,
+ const int32_t rollbackReasonIn,
+ const android::String16& failingPackageNameIn) override;
/**
* Binder call to get registered experiment IDs.
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 993db511d5d..1b502e2f9eb 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -1687,6 +1687,19 @@ message WatchdogRollbackOccurred {
optional string package_name = 2;
optional int32 package_version_code = 3;
+
+ enum RollbackReasonType {
+ REASON_UNKNOWN = 0;
+ REASON_NATIVE_CRASH = 1;
+ REASON_EXPLICIT_HEALTH_CHECK = 2;
+ REASON_APP_CRASH = 3;
+ REASON_APP_NOT_RESPONDING = 4;
+ }
+ optional RollbackReasonType rollback_reason = 4;
+
+ // Set by RollbackPackageHealthObserver to be the package that is failing when a rollback
+ // is initiated. Empty if the package is unknown.
+ optional string failing_package_name = 5;
}
/**
diff --git a/core/java/android/os/IStatsManager.aidl b/core/java/android/os/IStatsManager.aidl
index e3f9326048d..36ea1bcc91d 100644
--- a/core/java/android/os/IStatsManager.aidl
+++ b/core/java/android/os/IStatsManager.aidl
@@ -224,7 +224,7 @@ interface IStatsManager {
* Logs an event for watchdog rollbacks.
*/
oneway void sendWatchdogRollbackOccurredAtom(in int rollbackType, in String packageName,
- in long packageVersionCode);
+ in long packageVersionCode, in int rollbackReason, in String failingPackageName);
/**
* Returns the most recently registered experiment IDs.
diff --git a/core/java/android/util/StatsLog.java b/core/java/android/util/StatsLog.java
index f7077bb2a41..0bbed845b99 100644
--- a/core/java/android/util/StatsLog.java
+++ b/core/java/android/util/StatsLog.java
@@ -179,6 +179,8 @@ public final class StatsLog extends StatsLogInternal {
* @param rollbackType state of the rollback.
* @param packageName package name being rolled back.
* @param packageVersionCode version of the package being rolled back.
+ * @param rollbackReason reason the package is being rolled back.
+ * @param failingPackageName the package name causing the failure.
*
* @return True if the log request was sent to statsd.
*
@@ -186,7 +188,7 @@ public final class StatsLog extends StatsLogInternal {
*/
@RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
public static boolean logWatchdogRollbackOccurred(int rollbackType, String packageName,
- long packageVersionCode) {
+ long packageVersionCode, int rollbackReason, String failingPackageName) {
synchronized (sLogLock) {
try {
IStatsManager service = getIStatsManagerLocked();
@@ -198,7 +200,7 @@ public final class StatsLog extends StatsLogInternal {
}
service.sendWatchdogRollbackOccurredAtom(rollbackType, packageName,
- packageVersionCode);
+ packageVersionCode, rollbackReason, failingPackageName);
return true;
} catch (RemoteException e) {
sService = null;
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index dee89e5d5c4..501de7f63eb 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -56,6 +56,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
@@ -80,6 +81,22 @@ public class PackageWatchdog {
static final String PROPERTY_WATCHDOG_EXPLICIT_HEALTH_CHECK_ENABLED =
"watchdog_explicit_health_check_enabled";
+ public static final int FAILURE_REASON_UNKNOWN = 0;
+ public static final int FAILURE_REASON_NATIVE_CRASH = 1;
+ public static final int FAILURE_REASON_EXPLICIT_HEALTH_CHECK = 2;
+ public static final int FAILURE_REASON_APP_CRASH = 3;
+ public static final int FAILURE_REASON_APP_NOT_RESPONDING = 4;
+
+ @IntDef(prefix = { "FAILURE_REASON_" }, value = {
+ FAILURE_REASON_UNKNOWN,
+ FAILURE_REASON_NATIVE_CRASH,
+ FAILURE_REASON_EXPLICIT_HEALTH_CHECK,
+ FAILURE_REASON_APP_CRASH,
+ FAILURE_REASON_APP_NOT_RESPONDING
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FailureReasons {}
+
// Duration to count package failures before it resets to 0
private static final int DEFAULT_TRIGGER_FAILURE_DURATION_MS =
(int) TimeUnit.MINUTES.toMillis(1);
@@ -295,14 +312,15 @@ public class PackageWatchdog {
}
/**
- * Called when a process fails either due to a crash or ANR.
+ * Called when a process fails due to a crash, ANR or explicit health check.
*
* <p>For each package contained in the process, one registered observer with the least user
* impact will be notified for mitigation.
*
* <p>This method could be called frequently if there is a severe problem on the device.
*/
- public void onPackageFailure(List<VersionedPackage> packages) {
+ public void onPackageFailure(List<VersionedPackage> packages,
+ @FailureReasons int failureReason) {
mLongTaskHandler.post(() -> {
synchronized (mLock) {
if (mAllObservers.isEmpty()) {
@@ -333,7 +351,7 @@ public class PackageWatchdog {
// Execute action with least user impact
if (currentObserverToNotify != null) {
- currentObserverToNotify.execute(versionedPackage);
+ currentObserverToNotify.execute(versionedPackage, failureReason);
}
}
}
@@ -404,7 +422,7 @@ public class PackageWatchdog {
*
* @return {@code true} if action was executed successfully, {@code false} otherwise
*/
- boolean execute(VersionedPackage versionedPackage);
+ boolean execute(VersionedPackage versionedPackage, @FailureReasons int failureReason);
// TODO(b/120598832): Ensure uniqueness?
/**
@@ -648,7 +666,8 @@ public class PackageWatchdog {
// the tests don't install any packages
versionedPkg = new VersionedPackage(failedPackage, 0L);
}
- registeredObserver.execute(versionedPkg);
+ registeredObserver.execute(versionedPkg,
+ PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
}
}
}
@@ -759,7 +778,7 @@ public class PackageWatchdog {
final List<VersionedPackage> pkgList = Collections.singletonList(pkg);
final long failureCount = getTriggerFailureCount();
for (int i = 0; i < failureCount; i++) {
- onPackageFailure(pkgList);
+ onPackageFailure(pkgList, FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
}
});
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 1ff6f4dac72..a4c69506713 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -430,7 +430,8 @@ class AppErrors {
RescueParty.noteAppCrash(mContext, r.uid);
}
- mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode());
+ mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode(),
+ PackageWatchdog.FAILURE_REASON_APP_CRASH);
}
final int relaunchReason = r != null
@@ -884,7 +885,8 @@ class AppErrors {
}
// Notify PackageWatchdog without the lock held
if (packageList != null) {
- mPackageWatchdog.onPackageFailure(packageList);
+ mPackageWatchdog.onPackageFailure(packageList,
+ PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING);
}
}
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index 9c19aeccd59..3a94c931dd5 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -16,6 +16,13 @@
package com.android.server.rollback;
+import static android.util.StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_CRASH;
+import static android.util.StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_NOT_RESPONDING;
+import static android.util.StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_EXPLICIT_HEALTH_CHECK;
+import static android.util.StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH;
+import static android.util.StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN;
+
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -41,6 +48,7 @@ import android.util.StatsLog;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.server.PackageWatchdog;
+import com.android.server.PackageWatchdog.FailureReasons;
import com.android.server.PackageWatchdog.PackageHealthObserver;
import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
@@ -106,11 +114,19 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
}
@Override
- public boolean execute(VersionedPackage failedPackage) {
+ public boolean execute(VersionedPackage failedPackage, @FailureReasons int rollbackReason) {
RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
VersionedPackage moduleMetadataPackage = getModuleMetadataPackage();
RollbackInfo rollback = getAvailableRollback(rollbackManager, failedPackage);
+ int reasonToLog = mapFailureReasonToMetric(rollbackReason);
+ final String failedPackageToLog;
+ if (rollbackReason == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH) {
+ failedPackageToLog = SystemProperties.get(
+ "ro.init.updatable_crashing_process_name", "");
+ } else {
+ failedPackageToLog = failedPackage.getPackageName();
+ }
if (rollback == null) {
Slog.w(TAG, "Expected rollback but no valid rollback found for package: [ "
+ failedPackage.getPackageName() + "] with versionCode: ["
@@ -119,7 +135,8 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
}
logEvent(moduleMetadataPackage,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE);
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_INITIATE,
+ reasonToLog, failedPackageToLog);
LocalIntentReceiver rollbackReceiver = new LocalIntentReceiver((Intent result) -> {
int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
RollbackManager.STATUS_FAILURE);
@@ -136,11 +153,13 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
moduleMetadataPackage);
} else {
logEvent(moduleMetadataPackage,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS);
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
+ reasonToLog, failedPackageToLog);
}
} else {
logEvent(moduleMetadataPackage,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE);
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
+ reasonToLog, failedPackageToLog);
}
});
@@ -219,12 +238,14 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
}
if (sessionInfo.isStagedSessionApplied()) {
logEvent(oldModuleMetadataPackage,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS);
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
+ WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN, "");
} else if (sessionInfo.isStagedSessionReady()) {
// TODO: What do for staged session ready but not applied
} else {
logEvent(oldModuleMetadataPackage,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE);
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
+ WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN, "");
}
}
@@ -303,12 +324,16 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
saveLastStagedRollbackId(rollbackId);
logEvent(moduleMetadataPackage,
StatsLog
- .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED);
+ .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED,
+ WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN,
+ "");
mContext.getSystemService(PowerManager.class).reboot("Rollback staged install");
} else if (sessionInfo.isStagedSessionFailed()
&& markStagedSessionHandled(rollbackId)) {
logEvent(moduleMetadataPackage,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE);
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
+ WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN,
+ "");
mContext.unregisterReceiver(listener);
}
}
@@ -355,11 +380,12 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
return rollbackId;
}
- private static void logEvent(@Nullable VersionedPackage moduleMetadataPackage, int type) {
+ private static void logEvent(@Nullable VersionedPackage moduleMetadataPackage, int type,
+ int rollbackReason, @NonNull String failingPackageName) {
Slog.i(TAG, "Watchdog event occurred of type: " + type);
if (moduleMetadataPackage != null) {
StatsLog.logWatchdogRollbackOccurred(type, moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
+ moduleMetadataPackage.getVersionCode(), rollbackReason, failingPackageName);
}
}
@@ -371,7 +397,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
mNumberOfNativeCrashPollsRemaining--;
// Check if native watchdog reported a crash
if ("1".equals(SystemProperties.get("ro.init.updatable_crashing"))) {
- execute(getModuleMetadataPackage());
+ execute(getModuleMetadataPackage(), PackageWatchdog.FAILURE_REASON_NATIVE_CRASH);
// we stop polling after an attempt to execute rollback, regardless of whether the
// attempt succeeds or not
} else {
@@ -392,4 +418,20 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
+ "and mitigate native crashes");
mHandler.post(()->checkAndMitigateNativeCrashes());
}
+
+ private int mapFailureReasonToMetric(@FailureReasons int failureReason) {
+ switch (failureReason) {
+ case PackageWatchdog.FAILURE_REASON_NATIVE_CRASH:
+ return WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_NATIVE_CRASH;
+ case PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK:
+ return WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_EXPLICIT_HEALTH_CHECK;
+ case PackageWatchdog.FAILURE_REASON_APP_CRASH:
+ return WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_CRASH;
+ case PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING:
+ return WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_APP_NOT_RESPONDING;
+ default:
+ return WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_REASON__REASON_UNKNOWN;
+ }
+ }
+
}
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 232b5cb1702..31c6996217f 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -269,7 +269,8 @@ public class PackageWatchdogTest {
// Then fail APP_A below the threshold
for (int i = 0; i < watchdog.getTriggerFailureCount() - 1; i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
// Run handler so package failures are dispatched to observers
@@ -296,7 +297,8 @@ public class PackageWatchdogTest {
// Then fail APP_C (not observed) above the threshold
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_C, VERSION_CODE)));
+ watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_C, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
// Run handler so package failures are dispatched to observers
@@ -331,7 +333,8 @@ public class PackageWatchdogTest {
// Then fail APP_A (different version) above the threshold
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
watchdog.onPackageFailure(Arrays.asList(
- new VersionedPackage(APP_A, differentVersionCode)));
+ new VersionedPackage(APP_A, differentVersionCode)),
+ PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
// Run handler so package failures are dispatched to observers
@@ -372,7 +375,8 @@ public class PackageWatchdogTest {
watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE),
new VersionedPackage(APP_B, VERSION_CODE),
new VersionedPackage(APP_C, VERSION_CODE),
- new VersionedPackage(APP_D, VERSION_CODE)));
+ new VersionedPackage(APP_D, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
// Run handler so package failures are dispatched to observers
@@ -422,7 +426,8 @@ public class PackageWatchdogTest {
// Then fail APP_A above the threshold
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
@@ -439,7 +444,8 @@ public class PackageWatchdogTest {
// Then fail APP_A again above the threshold
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
@@ -456,7 +462,8 @@ public class PackageWatchdogTest {
// Then fail APP_A again above the threshold
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
@@ -473,7 +480,8 @@ public class PackageWatchdogTest {
// Then fail APP_A again above the threshold
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
// Run handler so package failures are dispatched to observers
mTestLooper.dispatchAll();
@@ -500,7 +508,8 @@ public class PackageWatchdogTest {
// Then fail APP_A above the threshold
for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
- watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)));
+ watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_UNKNOWN);
}
// Run handler so package failures are dispatched to observers
@@ -746,6 +755,44 @@ public class PackageWatchdogTest {
assertEquals(APP_A, observer.mFailedPackages.get(0));
}
+ /** Test that observers execute correctly for different failure reasons */
+ @Test
+ public void testFailureReasons() {
+ PackageWatchdog watchdog = createWatchdog();
+ TestObserver observer1 = new TestObserver(OBSERVER_NAME_1);
+ TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
+ TestObserver observer3 = new TestObserver(OBSERVER_NAME_3);
+ TestObserver observer4 = new TestObserver(OBSERVER_NAME_4);
+
+ watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
+ watchdog.startObservingHealth(observer2, Arrays.asList(APP_B), SHORT_DURATION);
+ watchdog.startObservingHealth(observer3, Arrays.asList(APP_C), SHORT_DURATION);
+ watchdog.startObservingHealth(observer4, Arrays.asList(APP_D), SHORT_DURATION);
+
+ for (int i = 0; i < watchdog.getTriggerFailureCount(); i++) {
+ watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_A, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_NATIVE_CRASH);
+ watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_B, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
+ watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_C, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_APP_CRASH);
+ watchdog.onPackageFailure(Arrays.asList(new VersionedPackage(APP_D, VERSION_CODE)),
+ PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING);
+ }
+
+ // Run handler so requests are dispatched to the controller
+ mTestLooper.dispatchAll();
+
+ assertTrue(observer1.getLastFailureReason()
+ == PackageWatchdog.FAILURE_REASON_NATIVE_CRASH);
+ assertTrue(observer2.getLastFailureReason()
+ == PackageWatchdog.FAILURE_REASON_EXPLICIT_HEALTH_CHECK);
+ assertTrue(observer3.getLastFailureReason()
+ == PackageWatchdog.FAILURE_REASON_APP_CRASH);
+ assertTrue(observer4.getLastFailureReason()
+ == PackageWatchdog.FAILURE_REASON_APP_NOT_RESPONDING);
+ }
+
private void adoptShellPermissions(String... permissions) {
InstrumentationRegistry
.getInstrumentation()
@@ -801,6 +848,7 @@ public class PackageWatchdogTest {
private static class TestObserver implements PackageHealthObserver {
private final String mName;
private int mImpact;
+ private int mLastFailureReason;
final List<String> mFailedPackages = new ArrayList<>();
TestObserver(String name) {
@@ -817,14 +865,19 @@ public class PackageWatchdogTest {
return mImpact;
}
- public boolean execute(VersionedPackage versionedPackage) {
+ public boolean execute(VersionedPackage versionedPackage, int failureReason) {
mFailedPackages.add(versionedPackage.getPackageName());
+ mLastFailureReason = failureReason;
return true;
}
public String getName() {
return mName;
}
+
+ public int getLastFailureReason() {
+ return mLastFailureReason;
+ }
}
private static class TestController extends ExplicitHealthCheckController {