More performance work:

- ActivityManager now keeps track of previous app as you
  move across the home app.
- Better debug info about why an activity is being destroyed.
- New performance tests.

Change-Id: I3a5ae7cb1b9f1624c6792a4f6184353f532b8f3b
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 310ace0..0c42926 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -293,7 +293,7 @@
     /**
      * Historical data of past broadcasts, for debugging.
      */
-    static final int MAX_BROADCAST_HISTORY = 100;
+    static final int MAX_BROADCAST_HISTORY = 25;
     final BroadcastRecord[] mBroadcastHistory
             = new BroadcastRecord[MAX_BROADCAST_HISTORY];
 
@@ -13898,7 +13898,7 @@
                         if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
                             // For these apps we will also finish their activities
                             // to help them free memory.
-                            mMainStack.destroyActivitiesLocked(app, false);
+                            mMainStack.destroyActivitiesLocked(app, false, "trim");
                         }
                     }
                     app.trimMemoryLevel = curLevel;
@@ -13962,7 +13962,7 @@
         }
 
         if (mAlwaysFinishActivities) {
-            mMainStack.destroyActivitiesLocked(null, false);
+            mMainStack.destroyActivitiesLocked(null, false, "always-finish");
         }
     }
 
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index a47502e..8435eaa 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -947,7 +947,7 @@
         r.state = ActivityState.STOPPED;
         if (!r.finishing) {
             if (r.configDestroy) {
-                destroyActivityLocked(r, true, false);
+                destroyActivityLocked(r, true, false, "stop-config");
                 resumeTopActivityLocked(null);
             }
         }
@@ -976,7 +976,7 @@
                     // instance right now, we need to first completely stop
                     // the current instance before starting the new one.
                     if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev);
-                    destroyActivityLocked(prev, true, false);
+                    destroyActivityLocked(prev, true, false, "pause-config");
                 } else {
                     mStoppingActivities.add(prev);
                     if (mStoppingActivities.size() > 3) {
@@ -1364,7 +1364,8 @@
                 }
             }
 
-            if (!prev.finishing && prev.app != null && prev.app != next.app) {
+            if (!prev.finishing && prev.app != null && prev.app != next.app
+                    && prev.app != mService.mHomeProcess) {
                 // We are switching to a new activity that is in a different
                 // process than the previous one.  Note the previous process,
                 // so we can try to keep it around.
@@ -3113,7 +3114,7 @@
                 if (DEBUG_STATES) Slog.v(TAG, "Stop failed; moving to STOPPED: " + r);
                 r.state = ActivityState.STOPPED;
                 if (r.configDestroy) {
-                    destroyActivityLocked(r, true, false);
+                    destroyActivityLocked(r, true, false, "stop-except");
                 }
             }
         }
@@ -3288,7 +3289,7 @@
         for (i=0; i<NF; i++) {
             ActivityRecord r = (ActivityRecord)finishes.get(i);
             synchronized (mService) {
-                destroyActivityLocked(r, true, false);
+                destroyActivityLocked(r, true, false, "finish-idle");
             }
         }
 
@@ -3487,7 +3488,7 @@
                 || prevState == ActivityState.INITIALIZING) {
             // If this activity is already stopped, we can just finish
             // it right now.
-            return destroyActivityLocked(r, true, true) ? null : r;
+            return destroyActivityLocked(r, true, true, "finish-imm") ? null : r;
         } else {
             // Need to go through the full pause cycle to get this
             // activity into the stopped state and then finish it.
@@ -3593,7 +3594,7 @@
         }
     }
     
-    final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj) {
+    final void destroyActivitiesLocked(ProcessRecord owner, boolean oomAdj, String reason) {
         for (int i=mHistory.size()-1; i>=0; i--) {
             ActivityRecord r = mHistory.get(i);
             if (owner != null && r.app != owner) {
@@ -3604,7 +3605,7 @@
             if (r.app != null && r.haveState && !r.visible && r.stopped && !r.finishing
                     && r.state != ActivityState.DESTROYING
                     && r.state != ActivityState.DESTROYED) {
-                destroyActivityLocked(r, true, oomAdj);
+                destroyActivityLocked(r, true, oomAdj, "trim");
             }
         }
     }
@@ -3616,13 +3617,13 @@
      * but then create a new client-side object for this same HistoryRecord.
      */
     final boolean destroyActivityLocked(ActivityRecord r,
-            boolean removeFromApp, boolean oomAdj) {
+            boolean removeFromApp, boolean oomAdj, String reason) {
         if (DEBUG_SWITCH) Slog.v(
             TAG, "Removing activity: token=" + r
               + ", app=" + (r.app != null ? r.app.processName : "(null)"));
         EventLog.writeEvent(EventLogTags.AM_DESTROY_ACTIVITY,
                 System.identityHashCode(r),
-                r.task.taskId, r.shortComponentName);
+                r.task.taskId, r.shortComponentName, reason);
 
         boolean removedFromHistory = false;
         
@@ -4109,7 +4110,7 @@
             if (r.app == null || r.app.thread == null) {
                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG,
                         "Switch is destroying non-running " + r);
-                destroyActivityLocked(r, true, false);
+                destroyActivityLocked(r, true, false, "config");
             } else if (r.state == ActivityState.PAUSING) {
                 // A little annoying: we are waiting for this activity to
                 // finish pausing.  Let's not do anything now, but just
diff --git a/services/java/com/android/server/am/EventLogTags.logtags b/services/java/com/android/server/am/EventLogTags.logtags
index aadd37d..a579f44 100644
--- a/services/java/com/android/server/am/EventLogTags.logtags
+++ b/services/java/com/android/server/am/EventLogTags.logtags
@@ -48,7 +48,7 @@
 # Reporting to applications that memory is low
 30017 am_low_memory (Num Processes|1|1)
 # An activity is being destroyed:
-30018 am_destroy_activity (Token|1|5),(Task ID|1|5),(Component Name|3)
+30018 am_destroy_activity (Token|1|5),(Task ID|1|5),(Component Name|3),(Reason|3)
 # An activity has been relaunched, resumed, and is now in the foreground:
 30019 am_relaunch_resume_activity (Token|1|5),(Task ID|1|5),(Component Name|3)
 # An activity has been relaunched:
diff --git a/tests/FrameworkPerf/res/layout/button_layout.xml b/tests/FrameworkPerf/res/layout/button_layout.xml
new file mode 100644
index 0000000..7786a25
--- /dev/null
+++ b/tests/FrameworkPerf/res/layout/button_layout.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+    <Button android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:text="FooBarYou" />
+</LinearLayout>
diff --git a/tests/FrameworkPerf/res/layout/image_button_layout.xml b/tests/FrameworkPerf/res/layout/image_button_layout.xml
new file mode 100644
index 0000000..65b12b3
--- /dev/null
+++ b/tests/FrameworkPerf/res/layout/image_button_layout.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+    <ImageButton android:layout_width="wrap_content" android:layout_height="wrap_content"
+            android:src="@drawable/stat_happy"/>
+</LinearLayout>
diff --git a/tests/FrameworkPerf/res/layout/large_layout.xml b/tests/FrameworkPerf/res/layout/large_layout.xml
index b6ac88c..39bbe34 100644
--- a/tests/FrameworkPerf/res/layout/large_layout.xml
+++ b/tests/FrameworkPerf/res/layout/large_layout.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- Copyright (C) 2011 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
diff --git a/tests/FrameworkPerf/res/layout/small_layout.xml b/tests/FrameworkPerf/res/layout/small_layout.xml
index 9fcbb26..e78a176 100644
--- a/tests/FrameworkPerf/res/layout/small_layout.xml
+++ b/tests/FrameworkPerf/res/layout/small_layout.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2009 The Android Open Source Project
+<!-- Copyright (C) 2011 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
diff --git a/tests/FrameworkPerf/res/layout/view_layout.xml b/tests/FrameworkPerf/res/layout/view_layout.xml
new file mode 100644
index 0000000..0171eef
--- /dev/null
+++ b/tests/FrameworkPerf/res/layout/view_layout.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" >
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+    <View android:layout_width="wrap_content" android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
index 5e15224..3979902 100644
--- a/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/FrameworkPerfActivity.java
@@ -20,6 +20,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Bundle;
@@ -29,13 +31,16 @@
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.SystemClock;
+import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.Xml;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.WindowManager;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
+import android.widget.Button;
 import android.widget.Spinner;
 import android.widget.TextView;
 
@@ -46,6 +51,9 @@
 import java.io.RandomAccessFile;
 import java.util.ArrayList;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
 /**
  * So you thought sync used up your battery life.
  */
@@ -57,8 +65,10 @@
 
     Spinner mFgSpinner;
     Spinner mBgSpinner;
-    TextView mLog;
     TextView mTestTime;
+    Button mStartButton;
+    Button mStopButton;
+    TextView mLog;
     PowerManager.WakeLock mPartialWakeLock;
 
     long mMaxRunTime = 5000;
@@ -100,12 +110,21 @@
             new WriteFileOp(), new ReadFileOp(),
             new ReadFileOp(), new WriteFileOp(),
             new ReadFileOp(), new ReadFileOp(),
+            new OpenXmlResOp(), new NoOp(),
+            new ReadXmlAttrsOp(), new NoOp(),
             new ParseXmlResOp(), new NoOp(),
             new ParseLargeXmlResOp(), new NoOp(),
             new LayoutInflaterOp(), new NoOp(),
             new LayoutInflaterLargeOp(), new NoOp(),
+            new LayoutInflaterViewOp(), new NoOp(),
+            new LayoutInflaterButtonOp(), new NoOp(),
+            new LayoutInflaterImageButtonOp(), new NoOp(),
+            new CreateBitmapOp(), new NoOp(),
+            new CreateRecycleBitmapOp(), new NoOp(),
             new LoadSmallBitmapOp(), new NoOp(),
+            new LoadRecycleSmallBitmapOp(), new NoOp(),
             new LoadLargeBitmapOp(), new NoOp(),
+            new LoadRecycleLargeBitmapOp(), new NoOp(),
             new LoadSmallScaledBitmapOp(), new NoOp(),
             new LoadLargeScaledBitmapOp(), new NoOp(),
     };
@@ -122,12 +141,21 @@
             new CreateWriteSyncFileOp(),
             new WriteFileOp(),
             new ReadFileOp(),
+            new OpenXmlResOp(),
+            new ReadXmlAttrsOp(),
             new ParseXmlResOp(),
             new ParseLargeXmlResOp(),
             new LayoutInflaterOp(),
             new LayoutInflaterLargeOp(),
+            new LayoutInflaterViewOp(),
+            new LayoutInflaterButtonOp(),
+            new LayoutInflaterImageButtonOp(),
+            new CreateBitmapOp(),
+            new CreateRecycleBitmapOp(),
             new LoadSmallBitmapOp(),
+            new LoadRecycleSmallBitmapOp(),
             new LoadLargeBitmapOp(),
+            new LoadRecycleLargeBitmapOp(),
             new LoadSmallScaledBitmapOp(),
             new LoadLargeScaledBitmapOp(),
     };
@@ -208,17 +236,22 @@
         mBgSpinner.setAdapter(adapter);
         mBgSpinner.setOnItemSelectedListener(this);
 
-        findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {
+        mTestTime = (TextView)findViewById(R.id.testtime);
+
+        mStartButton = (Button)findViewById(R.id.start);
+        mStartButton.setOnClickListener(new View.OnClickListener() {
             @Override public void onClick(View v) {
                 startRunning();
             }
         });
-        findViewById(R.id.stop).setOnClickListener(new View.OnClickListener() {
+        mStopButton = (Button)findViewById(R.id.stop);
+        mStopButton.setOnClickListener(new View.OnClickListener() {
             @Override public void onClick(View v) {
                 stopRunning();
             }
         });
-        mTestTime = (TextView)findViewById(R.id.testtime);
+        mStopButton.setEnabled(false);
+
         mLog = (TextView)findViewById(R.id.log);
 
         PowerManager pm = (PowerManager)getSystemService(POWER_SERVICE);
@@ -267,9 +300,17 @@
             fgOp = mFgTest;
             bgOp = mBgTest;
         } else if (mFgTest != null) {
+            // Skip null test.
+            if (mCurOpIndex == 0) {
+                mCurOpIndex = 1;
+            }
             fgOp = mFgTest;
             bgOp = mAvailOps[mCurOpIndex];
         } else {
+            // Skip null test.
+            if (mCurOpIndex == 0) {
+                mCurOpIndex = 1;
+            }
             fgOp = mAvailOps[mCurOpIndex];
             bgOp = mBgTest;
         }
@@ -297,12 +338,13 @@
                         stopRunning();
                         return;
                     }
-                }
-                mCurOpIndex++;
-                if (mCurOpIndex >= mAvailOps.length) {
-                    log("Finished");
-                    stopRunning();
-                    return;
+                } else {
+                    mCurOpIndex++;
+                    if (mCurOpIndex >= mAvailOps.length) {
+                        log("Finished");
+                        stopRunning();
+                        return;
+                    }
                 }
                 startCurOp();
             }
@@ -313,6 +355,11 @@
         if (!mStarted) {
             log("Start");
             mStarted = true;
+            mStartButton.setEnabled(false);
+            mStopButton.setEnabled(true);
+            mTestTime.setEnabled(false);
+            mFgSpinner.setEnabled(false);
+            mBgSpinner.setEnabled(false);
             updateWakeLock();
             startService(new Intent(this, SchedulerService.class));
             mCurOpIndex = 0;
@@ -325,6 +372,11 @@
     void stopRunning() {
         if (mStarted) {
             mStarted = false;
+            mStartButton.setEnabled(true);
+            mStopButton.setEnabled(false);
+            mTestTime.setEnabled(true);
+            mFgSpinner.setEnabled(true);
+            mBgSpinner.setEnabled(true);
             updateWakeLock();
             stopService(new Intent(this, SchedulerService.class));
             for (int i=0; i<mResults.size(); i++) {
@@ -333,7 +385,7 @@
                 float bgMsPerOp = result.getBgMsPerOp();
                 String fgMsPerOpStr = fgMsPerOp != 0 ? Float.toString(fgMsPerOp) : "";
                 String bgMsPerOpStr = bgMsPerOp != 0 ? Float.toString(bgMsPerOp) : "";
-                Log.i(TAG, "\t" + result.name + "\t" + result.fgOps
+                Log.i("PerfRes", "\t" + result.name + "\t" + result.fgOps
                         + "\t" + result.getFgMsPerOp() + "\t" + result.fgTime
                         + "\t" + result.fgLongName + "\t" + result.bgOps
                         + "\t" + result.getBgMsPerOp() + "\t" + result.bgTime
@@ -662,6 +714,71 @@
         }
     }
 
+    static class OpenXmlResOp extends Op {
+        Context mContext;
+
+        OpenXmlResOp() {
+            super("OpenXmlRes", "Open (and close) an XML resource");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            XmlResourceParser parser = mContext.getResources().getLayout(R.xml.simple);
+            parser.close();
+            return true;
+        }
+    }
+
+    static class ReadXmlAttrsOp extends Op {
+        Context mContext;
+        XmlResourceParser mParser;
+        AttributeSet mAttrs;
+
+        ReadXmlAttrsOp() {
+            super("ReadXmlAttrs", "Read attributes from an XML tag");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+            mParser = mContext.getResources().getLayout(R.xml.simple);
+            mAttrs = Xml.asAttributeSet(mParser);
+
+            int eventType;
+            try {
+                // Find the first <item> tag.
+                eventType = mParser.getEventType();
+                String tagName;
+                do {
+                    if (eventType == XmlPullParser.START_TAG) {
+                        tagName = mParser.getName();
+                        if (tagName.equals("item")) {
+                            break;
+                        }
+                    }
+                    eventType = mParser.next();
+                } while (eventType != XmlPullParser.END_DOCUMENT);
+            } catch (XmlPullParserException e) {
+                throw new RuntimeException("I died", e);
+            } catch (IOException e) {
+                throw new RuntimeException("I died", e);
+            }
+        }
+
+        void onTerm(Context context) {
+            mParser.close();
+        }
+
+        boolean onRun() {
+            TypedArray a = mContext.obtainStyledAttributes(mAttrs,
+                    com.android.internal.R.styleable.MenuItem);
+            a.recycle();
+            return true;
+        }
+    }
+
     static class ParseXmlResOp extends Op {
         Context mContext;
 
@@ -702,7 +819,7 @@
         Context mContext;
 
         LayoutInflaterOp() {
-            super("LayoutInflaterOp", "Inflate layout resource");
+            super("LayoutInflater", "Inflate layout resource");
         }
 
         void onInit(Context context, boolean foreground) {
@@ -724,7 +841,7 @@
         Context mContext;
 
         LayoutInflaterLargeOp() {
-            super("LayoutInflaterLargeOp", "Inflate large layout resource");
+            super("LayoutInflaterLarge", "Inflate large layout resource");
         }
 
         void onInit(Context context, boolean foreground) {
@@ -742,6 +859,111 @@
         }
     }
 
+    static class LayoutInflaterViewOp extends Op {
+        Context mContext;
+
+        LayoutInflaterViewOp() {
+            super("LayoutInflaterView", "Inflate layout with 50 View objects");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            if (Looper.myLooper() == null) {
+                Looper.prepare();
+            }
+            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+                    Context.LAYOUT_INFLATER_SERVICE);
+            inf.inflate(R.layout.view_layout, null);
+            return true;
+        }
+    }
+
+    static class LayoutInflaterButtonOp extends Op {
+        Context mContext;
+
+        LayoutInflaterButtonOp() {
+            super("LayoutInflaterButton", "Inflate layout with 50 Button objects");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            if (Looper.myLooper() == null) {
+                Looper.prepare();
+            }
+            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+                    Context.LAYOUT_INFLATER_SERVICE);
+            inf.inflate(R.layout.button_layout, null);
+            return true;
+        }
+    }
+
+    static class LayoutInflaterImageButtonOp extends Op {
+        Context mContext;
+
+        LayoutInflaterImageButtonOp() {
+            super("LayoutInflaterImageButton", "Inflate layout with 50 ImageButton objects");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            if (Looper.myLooper() == null) {
+                Looper.prepare();
+            }
+            LayoutInflater inf = (LayoutInflater)mContext.getSystemService(
+                    Context.LAYOUT_INFLATER_SERVICE);
+            inf.inflate(R.layout.image_button_layout, null);
+            return true;
+        }
+    }
+
+    static class CreateBitmapOp extends Op {
+        Context mContext;
+
+        CreateBitmapOp() {
+            super("CreateBitmap", "Create a Bitmap");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
+            return true;
+        }
+    }
+
+    static class CreateRecycleBitmapOp extends Op {
+        Context mContext;
+
+        CreateRecycleBitmapOp() {
+            super("CreateRecycleBitmap", "Create and recycle a Bitmap");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ARGB_8888);
+            bm.recycle();
+            return true;
+        }
+    }
+
     static class LoadSmallBitmapOp extends Op {
         Context mContext;
 
@@ -758,6 +980,26 @@
             opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
             Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
                     R.drawable.stat_sample, opts);
+            return true;
+        }
+    }
+
+    static class LoadRecycleSmallBitmapOp extends Op {
+        Context mContext;
+
+        LoadRecycleSmallBitmapOp() {
+            super("LoadRecycleSmallBitmap", "Load and recycle small raw bitmap");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+                    R.drawable.stat_sample, opts);
             bm.recycle();
             return true;
         }
@@ -779,6 +1021,26 @@
             opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
             Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
                     R.drawable.wallpaper_goldengate, opts);
+            return true;
+        }
+    }
+
+    static class LoadRecycleLargeBitmapOp extends Op {
+        Context mContext;
+
+        LoadRecycleLargeBitmapOp() {
+            super("LoadRecycleLargeBitmap", "Load and recycle large raw bitmap");
+        }
+
+        void onInit(Context context, boolean foreground) {
+            mContext = context;
+        }
+
+        boolean onRun() {
+            BitmapFactory.Options opts = new BitmapFactory.Options();
+            opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
+            Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
+                    R.drawable.wallpaper_goldengate, opts);
             bm.recycle();
             return true;
         }
@@ -800,7 +1062,6 @@
             opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
             Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
                     R.drawable.stat_sample_scale, opts);
-            bm.recycle();
             return true;
         }
     }
@@ -821,7 +1082,6 @@
             opts.inScreenDensity = DisplayMetrics.DENSITY_DEVICE;
             Bitmap bm = BitmapFactory.decodeResource(mContext.getResources(),
                     R.drawable.wallpaper_goldengate_scale, opts);
-            bm.recycle();
             return true;
         }
     }