Fix a couple issues with previous CL (keeping tasks hidden)

- Attempting to set the visiblity when the task org is set can happen too
  early and cause the app to not draw and preventing taskAppeared().
  Instead, move this to setHasBeenVisible() to be in line with other
  cases in the system where we defer setting visibility until the apps
  are good to go.  However, if we do this, we also need the first draw
  (including the starting window) to trigger setHasBeenVisible() to
  ensure the task org can hide it in time (the task org will also want
  to receive the task as soon as possible). As a result of moving it out
  of when the task org is set on the task the PIP transition then also
  has to defer setting the visibility of the activity until the first
  draw.
- Also fix a case where we are dispatching task info change before
  taskAppeared().  There's a brief period where the task has an organizer
  set, but the task org state has not added that task yet or sent
  taskAppeared() because it has not yet drawn.  But in that state, config
  changes still happen causing a task info changed call to the task org.

Bug: 152809695
Bug: 152134460
Test: Open a bubble, ensure that we don't see the task in fullscreen
      first.  Enter pip, ensure that we don't see flash of the task
      before SysUI can fade it in.
Test: atest PipAnimationControllerTest
Test: atest TaskOrganizerTests
Test: atest SplitScreenTests

Change-Id: I7d2ca2a2e538f07c73fff79686e040c159c1dce3
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index 243af14..9873031 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -131,6 +131,11 @@
         }
 
         void onTaskInfoChanged(Task task, ActivityManager.RunningTaskInfo taskInfo) {
+            if (!task.mCreatedByOrganizer && !task.mTaskAppearedSent) {
+                // Skip if the task has not yet received taskAppeared(), except for tasks created
+                // by the organizer that don't receive that signal
+                return;
+            }
             mDeferTaskOrgCallbacksConsumer.accept(() -> {
                 if (!task.isOrganized()) {
                     // This is safe to ignore if the task is no longer organized
@@ -145,6 +150,11 @@
         }
 
         void onBackPressedOnTaskRoot(Task task) {
+            if (!task.mCreatedByOrganizer && !task.mTaskAppearedSent) {
+                // Skip if the task has not yet received taskAppeared(), except for tasks created
+                // by the organizer that don't receive that signal
+                return;
+            }
             mDeferTaskOrgCallbacksConsumer.accept(() -> {
                 if (!task.isOrganized()) {
                     // This is safe to ignore if the task is no longer organized
@@ -193,23 +203,15 @@
                 mOrganizedTasks.add(t);
             }
             if (t.taskAppearedReady()) {
-                try {
-                    t.mTaskAppearedSent = true;
-                    mOrganizer.onTaskAppeared(t);
-                } catch (Exception e) {
-                    Slog.e(TAG, "Exception sending taskAppeared callback" + e);
-                }
+                t.mTaskAppearedSent = true;
+                mOrganizer.onTaskAppeared(t);
             }
         }
 
         void removeTask(Task t) {
             if (t.mTaskAppearedSent) {
-                try {
-                    t.mTaskAppearedSent = false;
-                    mOrganizer.onTaskVanished(t);
-                } catch (Exception e) {
-                    Slog.e(TAG, "Exception sending taskVanished callback" + e);
-                }
+                t.mTaskAppearedSent = false;
+                mOrganizer.onTaskVanished(t);
             }
             mOrganizedTasks.remove(t);
         }
@@ -460,9 +462,15 @@
         mTmpTaskInfo = null;
 
         if (task.isOrganized()) {
+            // Because we defer sending taskAppeared() until the app has drawn, we may receive a
+            // configuration change before the state actually has the task registered. As such we
+            // should ignore these change events to the organizer until taskAppeared(). If the task
+            // was created by the organizer, then we always send the info change.
             final TaskOrganizerState state = mTaskOrganizerStates.get(
                     task.mTaskOrganizer.asBinder());
-            state.mOrganizer.onTaskInfoChanged(task, newInfo);
+            if (state != null) {
+                state.mOrganizer.onTaskInfoChanged(task, newInfo);
+            }
         }
     }