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