Various performance and other work.

- IME service now switches between visible and perceptible depending on
  whether it is being showm, allowing us to more aggressively free its
  memory when not shown.

- The activity display time is no longer delayed by the activity
  transition animation.

- New -R (repeat) option for launching activities with the am command.

- Improved some documentation on Loader to be clear about some methods
  that apps should not normally call.

- FrameworkPerf test now allows you to select individual tests to run.

Change-Id: Id1f73de66dc93d63212183958a72119ad174318b
diff --git a/services/java/com/android/server/wm/AppWindowToken.java b/services/java/com/android/server/wm/AppWindowToken.java
index 61c96bb..0e3d20a 100644
--- a/services/java/com/android/server/wm/AppWindowToken.java
+++ b/services/java/com/android/server/wm/AppWindowToken.java
@@ -77,6 +77,9 @@
     // Last visibility state we reported to the app token.
     boolean reportedVisible;
 
+    // Last drawn state we reported to the app token.
+    boolean reportedDrawn;
+
     // Set to true when the token has been removed from the window mgr.
     boolean removed;
 
@@ -277,6 +280,7 @@
 
         int numInteresting = 0;
         int numVisible = 0;
+        int numDrawn = 0;
         boolean nowGone = true;
 
         if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Update reported visibility: " + this);
@@ -307,6 +311,7 @@
             }
             numInteresting++;
             if (win.isDrawnLw()) {
+                numDrawn++;
                 if (!win.isAnimating()) {
                     numVisible++;
                 }
@@ -316,9 +321,27 @@
             }
         }
 
+        boolean nowDrawn = numInteresting > 0 && numDrawn >= numInteresting;
         boolean nowVisible = numInteresting > 0 && numVisible >= numInteresting;
+        if (!nowGone) {
+            // If the app is not yet gone, then it can only become visible/drawn.
+            if (!nowDrawn) {
+                nowDrawn = reportedDrawn;
+            }
+            if (!nowVisible) {
+                nowVisible = reportedVisible;
+            }
+        }
         if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "VIS " + this + ": interesting="
                 + numInteresting + " visible=" + numVisible);
+        if (nowDrawn != reportedDrawn) {
+            if (nowDrawn) {
+                Message m = service.mH.obtainMessage(
+                        H.REPORT_APPLICATION_TOKEN_DRAWN, this);
+                service.mH.sendMessage(m);
+            }
+            reportedDrawn = nowDrawn;
+        }
         if (nowVisible != reportedVisible) {
             if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(
                     WindowManagerService.TAG, "Visibility changed in " + this
@@ -360,6 +383,7 @@
         pw.print(prefix); pw.print("hiddenRequested="); pw.print(hiddenRequested);
                 pw.print(" clientHidden="); pw.print(clientHidden);
                 pw.print(" willBeHidden="); pw.print(willBeHidden);
+                pw.print(" reportedDrawn="); pw.print(reportedDrawn);
                 pw.print(" reportedVisible="); pw.println(reportedVisible);
         if (paused || freezingScreen) {
             pw.print(prefix); pw.print("paused="); pw.print(paused);