Improve metrics logic
Test: atest BackgroundActivityStartController
Bug: 339245692
Flag: com.android.window.flags.bal_improved_metrics
Change-Id: Ic2fb6760e79beead80c5ea91e57308a236fb5474
diff --git a/core/java/android/window/flags/responsible_apis.aconfig b/core/java/android/window/flags/responsible_apis.aconfig
index 33af486..69cac6f 100644
--- a/core/java/android/window/flags/responsible_apis.aconfig
+++ b/core/java/android/window/flags/responsible_apis.aconfig
@@ -49,3 +49,10 @@
description: "Prevent BAL based on it is bound by foreground Uid but the app switch is stopped."
bug: "283801068"
}
+
+flag {
+ name: "bal_improved_metrics"
+ namespace: "responsible_apis"
+ description: "Improved metrics."
+ bug: "339245692"
+}
diff --git a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
index 0e446b8..ca4ae59 100644
--- a/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
+++ b/services/core/java/com/android/server/wm/BackgroundActivityStartController.java
@@ -39,6 +39,7 @@
import static com.android.server.wm.ActivityTaskSupervisor.getApplicationLabel;
import static com.android.server.wm.PendingRemoteAnimationRegistry.TIMEOUT_MS;
import static com.android.window.flags.Flags.balDontBringExistingBackgroundTaskStackToFg;
+import static com.android.window.flags.Flags.balImprovedMetrics;
import static com.android.window.flags.Flags.balImproveRealCallerVisibilityCheck;
import static com.android.window.flags.Flags.balRequireOptInByPendingIntentCreator;
import static com.android.window.flags.Flags.balRequireOptInSameUid;
@@ -1660,28 +1661,63 @@
(state.mOriginatingPendingIntent != null));
}
- @BalCode int code = finalVerdict.getCode();
- int callingUid = state.mCallingUid;
- int realCallingUid = state.mRealCallingUid;
- Intent intent = state.mIntent;
+ if (balImprovedMetrics()) {
+ if (shouldLogStats(finalVerdict, state)) {
+ String activityName;
+ if (shouldLogIntentActivity(finalVerdict, state)) {
+ Intent intent = state.mIntent;
+ activityName = intent == null ? "noIntent" // should never happen
+ : requireNonNull(intent.getComponent()).flattenToShortString();
+ } else {
+ activityName = "";
+ }
+ writeBalAllowedLog(activityName, finalVerdict.getCode(), state);
+ }
+ } else {
+ @BalCode int code = finalVerdict.getCode();
+ int callingUid = state.mCallingUid;
+ int realCallingUid = state.mRealCallingUid;
+ Intent intent = state.mIntent;
- if (code == BAL_ALLOW_PENDING_INTENT
- && (callingUid < Process.FIRST_APPLICATION_UID
- || realCallingUid < Process.FIRST_APPLICATION_UID)) {
- String activityName = intent != null
- ? requireNonNull(intent.getComponent()).flattenToShortString() : "";
- writeBalAllowedLog(activityName, BAL_ALLOW_PENDING_INTENT,
- state);
- }
- if (code == BAL_ALLOW_PERMISSION || code == BAL_ALLOW_FOREGROUND
- || code == BAL_ALLOW_SAW_PERMISSION) {
- // We don't need to know which activity in this case.
- writeBalAllowedLog("", code, state);
-
+ if (code == BAL_ALLOW_PENDING_INTENT
+ && (callingUid < Process.FIRST_APPLICATION_UID
+ || realCallingUid < Process.FIRST_APPLICATION_UID)) {
+ String activityName = intent != null
+ ? requireNonNull(intent.getComponent()).flattenToShortString() : "";
+ writeBalAllowedLog(activityName, BAL_ALLOW_PENDING_INTENT,
+ state);
+ }
+ if (code == BAL_ALLOW_PERMISSION || code == BAL_ALLOW_FOREGROUND
+ || code == BAL_ALLOW_SAW_PERMISSION) {
+ // We don't need to know which activity in this case.
+ writeBalAllowedLog("", code, state);
+ }
}
return finalVerdict;
}
+ @VisibleForTesting
+ boolean shouldLogStats(BalVerdict finalVerdict, BalState state) {
+ if (finalVerdict.blocks()) {
+ return false;
+ }
+ if (!state.isPendingIntent() && finalVerdict.getRawCode() == BAL_ALLOW_VISIBLE_WINDOW) {
+ return false;
+ }
+ if (state.mBalAllowedByPiSender.allowsBackgroundActivityStarts()
+ && state.mResultForRealCaller.getRawCode() == BAL_ALLOW_VISIBLE_WINDOW) {
+ return false;
+ }
+ return true;
+ }
+
+ @VisibleForTesting
+ boolean shouldLogIntentActivity(BalVerdict finalVerdict, BalState state) {
+ return finalVerdict.mBasedOnRealCaller
+ ? state.mRealCallingUid < Process.FIRST_APPLICATION_UID
+ : state.mCallingUid < Process.FIRST_APPLICATION_UID;
+ }
+
@VisibleForTesting void writeBalAllowedLog(String activityName, int code, BalState state) {
FrameworkStatsLog.write(FrameworkStatsLog.BAL_ALLOWED,
activityName,
diff --git a/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java
index 695faa5..39a2259 100644
--- a/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/BackgroundActivityStartControllerTests.java
@@ -19,6 +19,8 @@
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PENDING_INTENT;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_PERMISSION;
import static com.android.server.wm.BackgroundActivityStartController.BAL_ALLOW_VISIBLE_WINDOW;
+import static com.android.server.wm.BackgroundActivityStartController.BAL_BLOCK;
+import static com.android.window.flags.Flags.balImprovedMetrics;
import static com.google.common.truth.Truth.assertThat;
@@ -145,6 +147,16 @@
}
@Override
+ boolean shouldLogStats(BalVerdict finalVerdict, BalState state) {
+ return true;
+ }
+
+ @Override
+ boolean shouldLogIntentActivity(BalVerdict finalVerdict, BalState state) {
+ return true;
+ }
+
+ @Override
BalVerdict checkBackgroundActivityStartAllowedByCaller(BalState state) {
return mCallerVerdict.orElseGet(
() -> super.checkBackgroundActivityStartAllowedByCaller(state));
@@ -238,7 +250,12 @@
// assertions
assertThat(verdict.getCode()).isEqualTo(BackgroundActivityStartController.BAL_BLOCK);
- assertThat(mBalAllowedLogs).isEmpty(); // not allowed
+ if (balImprovedMetrics()) {
+ assertThat(mBalAllowedLogs).containsExactly(
+ new BalAllowedLog("package.app3/someClass", BAL_BLOCK));
+ } else {
+ assertThat(mBalAllowedLogs).isEmpty(); // not allowed
+ }
}
// Tests for BackgroundActivityStartController.checkBackgroundActivityStart
@@ -268,7 +285,12 @@
// assertions
assertThat(verdict).isEqualTo(BalVerdict.BLOCK);
- assertThat(mBalAllowedLogs).isEmpty(); // not allowed
+ if (balImprovedMetrics()) {
+ assertThat(mBalAllowedLogs).containsExactly(
+ new BalAllowedLog("package.app3/someClass", BAL_BLOCK));
+ } else {
+ assertThat(mBalAllowedLogs).isEmpty(); // not allowed
+ }
}
@Test
@@ -298,7 +320,12 @@
// assertions
assertThat(verdict).isEqualTo(callerVerdict);
- assertThat(mBalAllowedLogs).isEmpty(); // non-critical exception
+ if (balImprovedMetrics()) {
+ assertThat(mBalAllowedLogs).containsExactly(
+ new BalAllowedLog("package.app3/someClass", callerVerdict.getCode()));
+ } else {
+ assertThat(mBalAllowedLogs).isEmpty(); // non-critical exception
+ }
}
@Test
@@ -362,7 +389,13 @@
// assertions
assertThat(verdict).isEqualTo(callerVerdict);
- assertThat(mBalAllowedLogs).containsExactly(new BalAllowedLog("", callerVerdict.getCode()));
+ if (balImprovedMetrics()) {
+ assertThat(mBalAllowedLogs).containsExactly(
+ new BalAllowedLog("package.app3/someClass", callerVerdict.getCode()));
+ } else {
+ assertThat(mBalAllowedLogs).containsExactly(
+ new BalAllowedLog("", callerVerdict.getCode()));
+ }
}
@Test
@@ -398,7 +431,12 @@
// assertions
assertThat(verdict).isEqualTo(BalVerdict.BLOCK);
- assertThat(mBalAllowedLogs).isEmpty();
+ if (balImprovedMetrics()) {
+ assertThat(mBalAllowedLogs).containsExactly(
+ new BalAllowedLog("package.app3/someClass", BAL_BLOCK));
+ } else {
+ assertThat(mBalAllowedLogs).isEmpty();
+ }
}
@Test
@@ -430,7 +468,12 @@
// assertions
assertThat(verdict).isEqualTo(callerVerdict);
- assertThat(mBalAllowedLogs).isEmpty();
+ if (balImprovedMetrics()) {
+ assertThat(mBalAllowedLogs).containsExactly(
+ new BalAllowedLog("package.app3/someClass", callerVerdict.getCode()));
+ } else {
+ assertThat(mBalAllowedLogs).isEmpty();
+ }
}
@Test