Prevent premature display of starting window.

- When starting an activity, don't tell window manager to make the
windows visible is the keygaurd visibility for the activity is false.
Instead let the activity windows be made visible once the keygaurd
visibility transitions to true.
- Don't send duplicate visibility change request to window manger if we
are not changing state.

Fixes: 34545029
Test: Open a hangouts notification message on the lock-screen
and make sure the starting window doesn't flash.

Change-Id: I745e985766a1af97203e1d22b6443dabdd0c0363
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index f13dad7..4e00f2d 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -283,6 +283,7 @@
     boolean visible;        // does this activity's window need to be shown?
     boolean visibleIgnoringKeyguard; // is this activity visible, ignoring the fact that Keyguard
                                      // might hide this activity?
+    private boolean mLastSetWindowVisibility; // The last window visibility state that was set.
     private boolean mDeferHidingClient; // If true we told WM to defer reporting to the client
                                         // process that it is hidden.
     boolean sleeping;       // have we told the activity to sleep?
@@ -1581,6 +1582,10 @@
     }
 
     void setVisibility(boolean visible) {
+        if (mLastSetWindowVisibility == visible) {
+            return;
+        }
+        mLastSetWindowVisibility = visible;
         mWindowContainerController.setVisibility(visible, mDeferHidingClient);
         mStackSupervisor.mActivityMetricsLogger.notifyVisibilityChanged(this, visible);
     }
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index c5d5867..c56e4ea 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -1933,7 +1933,7 @@
      *
      * @return true if {@param r} is visible taken Keyguard state into account, false otherwise
      */
-    private boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible,
+    boolean checkKeyguardVisibility(ActivityRecord r, boolean shouldBeVisible,
             boolean isTop) {
         final boolean isInPinnedStack = r.getStack().getStackId() == PINNED_STACK_ID;
         final boolean keyguardShowing = mStackSupervisor.mKeyguardController.isKeyguardShowing();
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 4049500..8210c07 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1333,7 +1333,13 @@
         }
 
         r.startFreezingScreenLocked(app, 0);
-        r.setVisibility(true);
+        if (r.getStack().checkKeyguardVisibility(r, true /* shouldBeVisible */, true /* isTop */)) {
+            // We only set the visibility to true if the activity is allowed to be visible based on
+            // keyguard state. This avoids setting this into motion in window manager that is later
+            // cancelled due to later calls to ensure visible activities that set visibility back to
+            // false.
+            r.setVisibility(true);
+        }
 
         // schedule launch ticks to collect information about slow apps.
         r.startLaunchTickingLocked();