Merge "Add flicker test for minimum window size constraints." into main
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
index c9b35a0a..e1447dc 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/media/InfoMediaManagerTest.java
@@ -861,6 +861,23 @@
     }
 
     @Test
+    public void addMediaDevice_withAddresslessBluetoothDevice_shouldIgnoreDeviceAndNotCrash() {
+        MediaRoute2Info bluetoothRoute =
+                new MediaRoute2Info.Builder(TEST_BLUETOOTH_ROUTE).setAddress(null).build();
+
+        final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
+                mock(CachedBluetoothDeviceManager.class);
+        when(mLocalBluetoothManager.getCachedDeviceManager())
+                .thenReturn(cachedBluetoothDeviceManager);
+        when(cachedBluetoothDeviceManager.findDevice(any(BluetoothDevice.class))).thenReturn(null);
+
+        mInfoMediaManager.mMediaDevices.clear();
+        mInfoMediaManager.addMediaDevice(bluetoothRoute, TEST_SYSTEM_ROUTING_SESSION);
+
+        assertThat(mInfoMediaManager.mMediaDevices.size()).isEqualTo(0);
+    }
+
+    @Test
     public void onRoutesUpdated_setsFirstSelectedRouteAsCurrentConnectedDevice() {
         final CachedBluetoothDeviceManager cachedBluetoothDeviceManager =
                 mock(CachedBluetoothDeviceManager.class);
diff --git a/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt b/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
index af29b05..8d1de0e 100644
--- a/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
+++ b/packages/SystemUI/src-debug/com/android/systemui/log/DebugLogger.kt
@@ -62,6 +62,8 @@
      * @param error: a [Throwable] to log.
      * @param message: a lazily evaluated message you wish to log.
      */
+    @JvmOverloads
+    @JvmName("logcatMessage")
     inline fun Any.debugLog(
         enabled: Boolean = Build.IS_DEBUGGABLE,
         priority: Int = Log.DEBUG,
diff --git a/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt b/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
index 2764a1f..e29ce2d 100644
--- a/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
+++ b/packages/SystemUI/src-release/com/android/systemui/log/DebugLogger.kt
@@ -22,6 +22,7 @@
 /** An empty logger for release builds. */
 object DebugLogger {
 
+    @JvmOverloads
     @JvmName("logcatMessage")
     inline fun Any.debugLog(
         enabled: Boolean = Build.IS_DEBUGGABLE,
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
index c4f6cd9..8feefa4 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsActivity.java
@@ -62,6 +62,7 @@
 import com.android.internal.logging.UiEventLogger.UiEventEnum;
 import com.android.settingslib.Utils;
 import com.android.systemui.Flags;
+import com.android.systemui.log.DebugLogger;
 import com.android.systemui.res.R;
 import com.android.systemui.screenshot.scroll.CropView;
 import com.android.systemui.settings.UserTracker;
@@ -307,13 +308,16 @@
                 && mViewModel.getBacklinksLiveData().getValue() != null) {
             ClipData backlinksData = mViewModel.getBacklinksLiveData().getValue().getClipData();
             data.putParcelable(EXTRA_CLIP_DATA, backlinksData);
+
+            DebugLogger.INSTANCE.logcatMessage(this,
+                    () -> "setResultThenFinish: sending notes app ClipData");
         }
 
         try {
             mResultReceiver.send(Activity.RESULT_OK, data);
             logUiEvent(SCREENSHOT_FOR_NOTE_ACCEPTED);
         } catch (Exception e) {
-            Log.e(TAG, "Error while returning data to trampoline activity", e);
+            Log.e(TAG, "Error while sending data to trampoline activity", e);
         }
 
         // Nullify the ResultReceiver before finishing to avoid resending the result.
@@ -354,6 +358,7 @@
             }
         } catch (Exception e) {
             // Do nothing.
+            Log.e(TAG, "Error while sending trampoline activity error code: " + errorCode, e);
         }
 
         // Nullify the ResultReceiver to avoid resending the result.
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
index 0161f78..ef18fbe 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsTrampolineActivity.java
@@ -53,6 +53,7 @@
 import com.android.systemui.dagger.qualifiers.Application;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.log.DebugLogger;
 import com.android.systemui.notetask.NoteTaskController;
 import com.android.systemui.notetask.NoteTaskEntryPoint;
 import com.android.systemui.res.R;
@@ -265,11 +266,15 @@
             if (statusCode == CAPTURE_CONTENT_FOR_NOTE_SUCCESS) {
                 Uri uri = resultData.getParcelable(EXTRA_SCREENSHOT_URI, Uri.class);
                 convertedData.setData(uri);
-            }
 
-            if (resultData.containsKey(EXTRA_CLIP_DATA)) {
-                ClipData backlinksData = resultData.getParcelable(EXTRA_CLIP_DATA, ClipData.class);
-                convertedData.setClipData(backlinksData);
+                if (resultData.containsKey(EXTRA_CLIP_DATA)) {
+                    ClipData backlinksData = resultData.getParcelable(EXTRA_CLIP_DATA,
+                            ClipData.class);
+                    convertedData.setClipData(backlinksData);
+
+                    DebugLogger.INSTANCE.logcatMessage(this,
+                            () -> "onReceiveResult: sending notes app ClipData");
+                }
             }
 
             // Broadcast no longer required, setting it to null.
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
index d30d518..8c833ec 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/appclips/AppClipsViewModel.java
@@ -54,6 +54,7 @@
 
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.log.DebugLogger;
 import com.android.systemui.screenshot.AssistContentRequester;
 import com.android.systemui.screenshot.ImageExporter;
 
@@ -143,6 +144,7 @@
      * @param displayId       id of the display to query tasks for Backlinks data
      */
     void triggerBacklinks(Set<Integer> taskIdsToIgnore, int displayId) {
+        DebugLogger.INSTANCE.logcatMessage(this, () -> "Backlinks triggered");
         mBgExecutor.execute(() -> {
             ListenableFuture<InternalBacklinksData> backlinksData = getBacklinksData(
                     taskIdsToIgnore, displayId);
@@ -247,6 +249,10 @@
     }
 
     private boolean shouldIncludeTask(RootTaskInfo taskInfo, Set<Integer> taskIdsToIgnore) {
+        DebugLogger.INSTANCE.logcatMessage(this,
+                () -> String.format("shouldIncludeTask taskId %d; topActivity %s", taskInfo.taskId,
+                        taskInfo.topActivity));
+
         // Only consider tasks that shouldn't be ignored, are visible, running, and have a launcher
         // icon. Furthermore, types such as launcher/home/dock/assistant are ignored.
         return !taskIdsToIgnore.contains(taskInfo.taskId)
@@ -267,6 +273,10 @@
 
     private ListenableFuture<InternalBacklinksData> getBacklinksDataForTaskId(
             RootTaskInfo taskInfo) {
+        DebugLogger.INSTANCE.logcatMessage(this,
+                () -> String.format("getBacklinksDataForTaskId for taskId %d; topActivity %s",
+                        taskInfo.taskId, taskInfo.topActivity));
+
         SettableFuture<InternalBacklinksData> backlinksData = SettableFuture.create();
         int taskId = taskInfo.taskId;
         mAssistContentRequester.requestAssistContent(taskId, assistContent ->
@@ -295,6 +305,10 @@
      */
     private InternalBacklinksData getBacklinksDataFromAssistContent(RootTaskInfo taskInfo,
             @Nullable AssistContent content) {
+        DebugLogger.INSTANCE.logcatMessage(this,
+                () -> String.format("getBacklinksDataFromAssistContent taskId %d; topActivity %s",
+                        taskInfo.taskId, taskInfo.topActivity));
+
         String appName = getAppNameOfTask(taskInfo);
         String packageName = taskInfo.topActivity.getPackageName();
         Drawable appIcon = taskInfo.topActivityInfo.loadIcon(mPackageManager);
@@ -307,22 +321,34 @@
 
         // First preference is given to app provided uri.
         if (content.isAppProvidedWebUri()) {
+            DebugLogger.INSTANCE.logcatMessage(this,
+                    () -> "getBacklinksDataFromAssistContent: app has provided a uri");
+
             Uri uri = content.getWebUri();
             Intent backlinksIntent = new Intent(ACTION_VIEW).setData(uri);
             if (doesIntentResolveToSamePackage(backlinksIntent, packageName)) {
+                DebugLogger.INSTANCE.logcatMessage(this,
+                        () -> "getBacklinksDataFromAssistContent: using app provided uri");
                 return new InternalBacklinksData(ClipData.newRawUri(appName, uri), appIcon);
             }
         }
 
         // Second preference is given to app provided, hopefully deep-linking, intent.
         if (content.isAppProvidedIntent()) {
+            DebugLogger.INSTANCE.logcatMessage(this,
+                    () -> "getBacklinksDataFromAssistContent: app has provided an intent");
+
             Intent backlinksIntent = content.getIntent();
             if (doesIntentResolveToSamePackage(backlinksIntent, packageName)) {
+                DebugLogger.INSTANCE.logcatMessage(this,
+                        () -> "getBacklinksDataFromAssistContent: using app provided intent");
                 return new InternalBacklinksData(ClipData.newIntent(appName, backlinksIntent),
                         appIcon);
             }
         }
 
+        DebugLogger.INSTANCE.logcatMessage(this,
+                () -> "getBacklinksDataFromAssistContent: using fallback");
         return fallback;
     }