Merge "Add the variable speed tests to the test runner."
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java
index 5d89957..ba6d567 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java
@@ -50,6 +50,7 @@
     private static final String TAG = "MonkeyStub";
     /* The version of the monkey network protocol */
     public static final int MONKEY_NETWORK_VERSION = 2;
+    private static DeferredReturn deferredReturn;
 
     /**
      * ReturnValue from the MonkeyCommand that indicates whether the
@@ -378,6 +379,52 @@
     }
 
     /**
+     * Command to defer the return of another command until the given event occurs.
+     * deferreturn takes three arguments. It takes an event to wait for (e.g. waiting for the
+     * device to display a different activity would the "screenchange" event), a
+     * timeout, which is the number of microseconds to wait for the event to occur, and it takes
+     * a command. The command can be any other Monkey command that can be issued over the network
+     * (e.g. press KEYCODE_HOME). deferreturn will then run this command, return an OK, wait for
+     * the event to occur and return the deferred return value when either the event occurs or
+     * when the timeout is reached (whichever occurs first). Note that there is no difference
+     * between an event occurring and the timeout being reached; the client will have to verify
+     * that the change actually occured.
+     *
+     * Example:
+     *     deferreturn screenchange 1000 press KEYCODE_HOME
+     * This command will press the home key on the device and then wait for the screen to change
+     * for up to one second. Either the screen will change, and the results fo the key press will
+     * be returned to the client, or the timeout will be reached, and the results for the key
+     * press will be returned to the client.
+     */
+    private static class DeferReturnCommand implements MonkeyCommand {
+        // deferreturn [event] [timeout (ms)] [command]
+        // deferreturn screenchange 100 tap 10 10
+        public MonkeyCommandReturn translateCommand(List<String> command,
+                                                    CommandQueue queue) {
+            if (command.size() > 3) {
+                String event = command.get(1);
+                int eventId;
+                if (event.equals("screenchange")) {
+                    eventId = DeferredReturn.ON_WINDOW_STATE_CHANGE;
+                } else {
+                    return EARG;
+                }
+                long timeout = Long.parseLong(command.get(2));
+                MonkeyCommand deferredCommand = COMMAND_MAP.get(command.get(3));
+                if (deferredCommand != null) {
+                    List<String> parts = command.subList(3, command.size());
+                    MonkeyCommandReturn ret = deferredCommand.translateCommand(parts, queue);
+                    deferredReturn = new DeferredReturn(eventId, ret, timeout);
+                    return OK;
+                }
+            }
+            return EARG;
+        }
+    }
+
+
+    /**
      * Force the device to wake up.
      *
      * @return true if woken up OK.
@@ -415,6 +462,7 @@
         COMMAND_MAP.put("getrootview", new MonkeySourceNetworkViews.GetRootViewCommand());
         COMMAND_MAP.put("getviewswithtext",
                         new MonkeySourceNetworkViews.GetViewsWithTextCommand());
+        COMMAND_MAP.put("deferreturn", new DeferReturnCommand());
     }
 
     // QUIT command
@@ -458,6 +506,40 @@
         }
     };
 
+    // A holder class for a deferred return value. This allows us to defer returning the success of
+    // a call until a given event has occurred.
+    private static class DeferredReturn {
+        public static final int ON_WINDOW_STATE_CHANGE = 1;
+
+        private int event;
+        private MonkeyCommandReturn deferredReturn;
+        private long timeout;
+
+        public DeferredReturn(int event, MonkeyCommandReturn deferredReturn, long timeout) {
+            this.event = event;
+            this.deferredReturn = deferredReturn;
+            this.timeout = timeout;
+        }
+
+        /**
+         * Wait until the given event has occurred before returning the value.
+         * @return The MonkeyCommandReturn from the command that was deferred.
+         */
+        public MonkeyCommandReturn waitForEvent() {
+            switch(event) {
+                case ON_WINDOW_STATE_CHANGE:
+                    try {
+                        synchronized(MonkeySourceNetworkViews.sConnection) {
+                            MonkeySourceNetworkViews.sConnection.wait(timeout);
+                        }
+                    } catch(InterruptedException e) {
+                        Log.d(TAG, "Deferral interrupted: " + e.getMessage());
+                    }
+            }
+            return deferredReturn;
+        }
+    };
+
     private final CommandQueueImpl commandQueue = new CommandQueueImpl();
 
     private BufferedReader input;
@@ -571,23 +653,28 @@
             MonkeyCommand command = COMMAND_MAP.get(parts.get(0));
             if (command != null) {
                 MonkeyCommandReturn ret = command.translateCommand(parts, commandQueue);
-                if (ret.wasSuccessful()) {
-                    if (ret.hasMessage()) {
-                        returnOk(ret.getMessage());
-                    } else {
-                        returnOk();
-                    }
-                } else {
-                    if (ret.hasMessage()) {
-                        returnError(ret.getMessage());
-                    } else {
-                        returnError();
-                    }
-                }
+                handleReturn(ret);
             }
         }
     }
 
+    private void handleReturn(MonkeyCommandReturn ret) {
+        if (ret.wasSuccessful()) {
+            if (ret.hasMessage()) {
+                returnOk(ret.getMessage());
+            } else {
+                returnOk();
+            }
+        } else {
+            if (ret.hasMessage()) {
+                returnError(ret.getMessage());
+            } else {
+                returnError();
+            }
+        }
+    }
+
+
     public MonkeyEvent getNextEvent() {
         if (!started) {
             try {
@@ -611,6 +698,16 @@
                     return queuedEvent;
                 }
 
+                // Check to see if we have any returns that have been deferred. If so, now that
+                // we've run the queued commands, wait for the given event to happen (or the timeout
+                // to be reached), and handle the deferred MonkeyCommandReturn.
+                if (deferredReturn != null) {
+                    Log.d(TAG, "Waiting for event");
+                    MonkeyCommandReturn ret = deferredReturn.waitForEvent();
+                    deferredReturn = null;
+                    handleReturn(ret);
+                }
+
                 String command = input.readLine();
                 if (command == null) {
                     Log.d(TAG, "Connection dropped.");
diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java
index f96f133..a32b8a5 100644
--- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java
+++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkViews.java
@@ -111,7 +111,11 @@
             public void onInterrupt() {}
 
             public void onAccessibilityEvent(AccessibilityEvent event) {
-                 sLastAccessibilityEvent.set(AccessibilityEvent.obtain(event));
+                Log.d(TAG, "Accessibility Event");
+                sLastAccessibilityEvent.set(AccessibilityEvent.obtain(event));
+                synchronized(sConnection) {
+                    sConnection.notifyAll();
+                }
             }
         };
         IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface(
@@ -402,6 +406,11 @@
                 if (node.isPassword()){
                     return new MonkeyCommandReturn(false, "Node contains a password");
                 }
+                /* Occasionally we get a null from the accessibility API, rather than an empty
+                 * string */
+                if (node.getText() == null) {
+                    return new MonkeyCommandReturn(true, "");
+                }
                 return new MonkeyCommandReturn(true, node.getText().toString());
             }
             return EARG;
diff --git a/ide/eclipse/.classpath b/ide/eclipse/.classpath
index 470c584..4d00c06 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -35,7 +35,6 @@
 	<classpathentry kind="src" path="frameworks/base/cmds/pm/src"/>
 	<classpathentry kind="src" path="frameworks/base/cmds/svc/src"/>
 	<classpathentry kind="src" path="frameworks/base/core/java"/>
-	<classpathentry kind="src" path="frameworks/base/core/config/sdk"/>
 	<classpathentry kind="src" path="frameworks/base/drm/java"/>
 	<classpathentry kind="src" path="frameworks/base/graphics/java"/>
 	<classpathentry kind="src" path="frameworks/base/icu4j/java"/>
@@ -56,6 +55,7 @@
 	<classpathentry kind="src" path="frameworks/ex/carousel/java"/>
 	<classpathentry kind="src" path="frameworks/ex/chips/src"/>
 	<classpathentry kind="src" path="frameworks/ex/common/java"/>
+	<classpathentry kind="src" path="frameworks/ex/variablespeed/src"/>
 	<classpathentry kind="src" path="frameworks/opt/calendar/src"/>
 	<classpathentry kind="src" path="frameworks/opt/vcard/java"/>
 	<classpathentry kind="src" path="frameworks/support/v13/java"/>
@@ -74,7 +74,6 @@
 	<classpathentry kind="src" path="development/samples/SkeletonApp/tests/src"/>
 	<classpathentry kind="src" path="development/samples/Snake/src"/>
 	<classpathentry kind="src" path="development/samples/Snake/tests/src"/>
-	<classpathentry kind="src" path="development/apps/Term/src"/>
 	<classpathentry kind="src" path="libcore/dalvik/src/main/java"/>
 	<classpathentry kind="src" path="libcore/json/src/main/java"/>
 	<classpathentry kind="src" path="libcore/junit/src/main/java"/>
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index 1fcf7ee..b70ed4d 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -263,6 +263,15 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".app.FragmentCustomAnimations"
+                android:label="@string/fragment_custom_animations"
+                android:enabled="@bool/atLeastHoneycombMR2">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".app.FragmentHideShow"
                 android:label="@string/fragment_hide_show"
                 android:windowSoftInputMode="stateUnchanged"
@@ -480,6 +489,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".app.RemoteService$BindingOptions"
+                android:label="@string/activity_remote_service_binding_options">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <service android:name=".app.ServiceStartArguments" />
 
         <activity android:name=".app.ServiceStartArguments$Controller"
@@ -2003,6 +2020,16 @@
                        android:value=".app.SearchQueryResults" />
         </activity>
 
+        <activity android:name=".view.SearchViewAlwaysVisible" android:label="Views/Search View/Always Expanded"
+                android:theme="@android:style/Theme.Holo">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+            <meta-data android:name="android.app.default_searchable"
+                       android:value=".app.SearchQueryResults" />
+        </activity>
+
         <activity android:name=".view.SearchViewFilterMode" android:label="Views/Search View/Filter"
                 android:theme="@android:style/Theme.Holo">
             <intent-filter>
diff --git a/samples/ApiDemos/res/animator/fragment_slide_left_enter.xml b/samples/ApiDemos/res/animator/fragment_slide_left_enter.xml
new file mode 100644
index 0000000..11f1ee6
--- /dev/null
+++ b/samples/ApiDemos/res/animator/fragment_slide_left_enter.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
+        android:interpolator="@android:interpolator/decelerate_quint"
+        android:valueFrom="100dp" android:valueTo="0dp"
+        android:valueType="floatType"
+        android:propertyName="translationX"
+        android:duration="@android:integer/config_mediumAnimTime" />
+    <objectAnimator
+        android:interpolator="@android:interpolator/decelerate_quint"
+        android:valueFrom="0.0" android:valueTo="1.0"
+        android:valueType="floatType"
+        android:propertyName="alpha"
+        android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/ApiDemos/res/animator/fragment_slide_left_exit.xml b/samples/ApiDemos/res/animator/fragment_slide_left_exit.xml
new file mode 100644
index 0000000..096f04a
--- /dev/null
+++ b/samples/ApiDemos/res/animator/fragment_slide_left_exit.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
+        android:interpolator="@android:interpolator/decelerate_quint"
+        android:valueFrom="0dp" android:valueTo="-100dp"
+        android:valueType="floatType"
+        android:propertyName="translationX"
+        android:duration="@android:integer/config_mediumAnimTime" />
+    <objectAnimator
+        android:interpolator="@android:interpolator/decelerate_quint"
+        android:valueFrom="1.0" android:valueTo="0.0"
+        android:valueType="floatType"
+        android:propertyName="alpha"
+        android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/ApiDemos/res/animator/fragment_slide_right_enter.xml b/samples/ApiDemos/res/animator/fragment_slide_right_enter.xml
new file mode 100644
index 0000000..86f53be
--- /dev/null
+++ b/samples/ApiDemos/res/animator/fragment_slide_right_enter.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
+        android:interpolator="@android:interpolator/decelerate_quint"
+        android:valueFrom="-100dp" android:valueTo="0dp"
+        android:valueType="floatType"
+        android:propertyName="translationX"
+        android:duration="@android:integer/config_mediumAnimTime" />
+    <objectAnimator
+        android:interpolator="@android:interpolator/decelerate_quint"
+        android:valueFrom="0.0" android:valueTo="1.0"
+        android:valueType="floatType"
+        android:propertyName="alpha"
+        android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/ApiDemos/res/animator/fragment_slide_right_exit.xml b/samples/ApiDemos/res/animator/fragment_slide_right_exit.xml
new file mode 100644
index 0000000..7d02956
--- /dev/null
+++ b/samples/ApiDemos/res/animator/fragment_slide_right_exit.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
+        android:interpolator="@android:interpolator/decelerate_quint"
+        android:valueFrom="0dp" android:valueTo="100dp"
+        android:valueType="floatType"
+        android:propertyName="translationX"
+        android:duration="@android:integer/config_mediumAnimTime" />
+    <objectAnimator
+        android:interpolator="@android:interpolator/decelerate_quint"
+        android:valueFrom="1.0" android:valueTo="0.0"
+        android:valueType="floatType"
+        android:propertyName="alpha"
+        android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/ApiDemos/res/layout/remote_binding_options.xml b/samples/ApiDemos/res/layout/remote_binding_options.xml
new file mode 100644
index 0000000..aec33f8
--- /dev/null
+++ b/samples/ApiDemos/res/layout/remote_binding_options.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2007 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.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="Demonstrates various options that can be used when binding to a service to modify its process management."/>
+
+    <TextView android:id="@+id/callback"
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:gravity="center_horizontal" android:paddingBottom="4dip"/>
+
+    <ScrollView android:layout_width="match_parent" android:layout_height="match_parent">
+        <LinearLayout android:orientation="vertical"
+            android:gravity="center_horizontal"
+            android:layout_width="match_parent" android:layout_height="wrap_content">
+            <Button android:id="@+id/bind_normal"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:text="Normal">
+                <requestFocus />
+            </Button>
+
+            <Button android:id="@+id/bind_not_foreground"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:text="Not Foreground">
+            </Button>
+
+            <Button android:id="@+id/bind_above_client"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:text="Above Client">
+            </Button>
+
+            <Button android:id="@+id/bind_allow_oom"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:text="Allow OOM Management">
+            </Button>
+
+            <Button android:id="@+id/bind_waive_priority"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:text="Waive Priority">
+            </Button>
+
+            <Button android:id="@+id/bind_important"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:text="Important">
+            </Button>
+
+            <Button android:id="@+id/bind_with_activity"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:text="Adjust With Activity">
+            </Button>
+
+            <Button android:id="@+id/unbind"
+                android:layout_width="wrap_content" android:layout_height="wrap_content"
+                android:text="@string/unbind_service">
+            </Button>
+        </LinearLayout>
+    </ScrollView>
+
+</LinearLayout>
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index c87c563..1aaff9a 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -114,6 +114,8 @@
     <string name="fragment_arguments_embedded">From Attributes</string>
     <string name="fragment_arguments_embedded_land">Landscape Only</string>
 
+    <string name="fragment_custom_animations">App/Fragment/Custom Animations</string>
+
     <string name="fragment_hide_show">App/Fragment/Hide and Show</string>
 
     <string name="fragment_context_menu">App/Fragment/Context Menu</string>
@@ -206,8 +208,11 @@
     <string name="kill_process">Kill Process</string>
     <string name="remote_service_connected">Connected to remote service</string>
     <string name="remote_service_disconnected">Disconnected from remote service</string>
+    <string name="remote_service_unbind_disconn">Unbinding due to disconnect</string>
     <string name="remote_call_failed">Failure calling remote service</string>
 
+    <string name="activity_remote_service_binding_options">App/Service/Remote Service Binding Options</string>
+
     <string name="service_start_arguments_label">Sample Service Start Arguments
     </string>
 
diff --git a/samples/ApiDemos/res/xml/searchable.xml b/samples/ApiDemos/res/xml/searchable.xml
index df4ef7a..a2d048a 100644
--- a/samples/ApiDemos/res/xml/searchable.xml
+++ b/samples/ApiDemos/res/xml/searchable.xml
@@ -19,8 +19,7 @@
 
 <searchable xmlns:android="http://schemas.android.com/apk/res/android"
     android:label="@string/search_label"
-    android:hint="@string/search_hint" 
-    android:searchMode="showSearchLabelAsBadge"
+    android:hint="@string/search_hint"
     
     android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
     android:voiceLanguageModel="free_form"
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/FragmentCustomAnimations.java b/samples/ApiDemos/src/com/example/android/apis/app/FragmentCustomAnimations.java
new file mode 100644
index 0000000..157b624
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/app/FragmentCustomAnimations.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+package com.example.android.apis.app;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.Fragment;
+import android.app.FragmentTransaction;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Demonstrates the use of custom animations in a FragmentTransaction when
+ * pushing and popping a stack.
+ */
+public class FragmentCustomAnimations extends Activity {
+    int mStackLevel = 1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_stack);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.new_fragment);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                addFragmentToStack();
+            }
+        });
+
+        if (savedInstanceState == null) {
+            // Do first time initialization -- add initial fragment.
+            Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+            FragmentTransaction ft = getFragmentManager().beginTransaction();
+            ft.add(R.id.simple_fragment, newFragment).commit();
+        } else {
+            mStackLevel = savedInstanceState.getInt("level");
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt("level", mStackLevel);
+    }
+
+//BEGIN_INCLUDE(add_stack)
+    void addFragmentToStack() {
+        mStackLevel++;
+
+        // Instantiate a new fragment.
+        Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+
+        // Add the fragment to the activity, pushing this transaction
+        // on to the back stack.
+        FragmentTransaction ft = getFragmentManager().beginTransaction();
+        ft.setCustomAnimations(R.animator.fragment_slide_left_enter,
+                R.animator.fragment_slide_left_exit,
+                R.animator.fragment_slide_right_enter,
+                R.animator.fragment_slide_right_exit);
+        ft.replace(R.id.simple_fragment, newFragment);
+        ft.addToBackStack(null);
+        ft.commit();
+    }
+//END_INCLUDE(add_stack)
+
+//BEGIN_INCLUDE(fragment)
+    public static class CountingFragment extends Fragment {
+        int mNum;
+
+        /**
+         * Create a new instance of CountingFragment, providing "num"
+         * as an argument.
+         */
+        static CountingFragment newInstance(int num) {
+            CountingFragment f = new CountingFragment();
+
+            // Supply num input as an argument.
+            Bundle args = new Bundle();
+            args.putInt("num", num);
+            f.setArguments(args);
+
+            return f;
+        }
+
+        /**
+         * When creating, retrieve this instance's number from its arguments.
+         */
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mNum = getArguments() != null ? getArguments().getInt("num") : 1;
+        }
+
+        /**
+         * The Fragment's UI is just a simple text view showing its
+         * instance number.
+         */
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.hello_world, container, false);
+            View tv = v.findViewById(R.id.text);
+            ((TextView)tv).setText("Fragment #" + mNum);
+            tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
+            return v;
+        }
+    }
+//END_INCLUDE(fragment)
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java b/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
index aade659..76458f4 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.java
@@ -461,4 +461,192 @@
         };
     }
 // END_INCLUDE(calling_a_service)
+
+    // ----------------------------------------------------------------------
+
+    /**
+     * Examples of behavior of different bind flags.</p>
+     */
+ // BEGIN_INCLUDE(calling_a_service)
+    public static class BindingOptions extends Activity {
+        ServiceConnection mCurConnection;
+        TextView mCallbackText;
+
+        class MyServiceConnection implements ServiceConnection {
+            final boolean mUnbindOnDisconnect;
+
+            public MyServiceConnection() {
+                mUnbindOnDisconnect = false;
+            }
+
+            public MyServiceConnection(boolean unbindOnDisconnect) {
+                mUnbindOnDisconnect = unbindOnDisconnect;
+            }
+
+            public void onServiceConnected(ComponentName className,
+                    IBinder service) {
+                if (mCurConnection != this) {
+                    return;
+                }
+                mCallbackText.setText("Attached.");
+                Toast.makeText(BindingOptions.this, R.string.remote_service_connected,
+                        Toast.LENGTH_SHORT).show();
+            }
+
+            public void onServiceDisconnected(ComponentName className) {
+                if (mCurConnection != this) {
+                    return;
+                }
+                mCallbackText.setText("Disconnected.");
+                Toast.makeText(BindingOptions.this, R.string.remote_service_disconnected,
+                        Toast.LENGTH_SHORT).show();
+                if (mUnbindOnDisconnect) {
+                    unbindService(this);
+                    mCurConnection = null;
+                    Toast.makeText(BindingOptions.this, R.string.remote_service_unbind_disconn,
+                            Toast.LENGTH_SHORT).show();
+                }
+            }
+        }
+
+        /**
+         * Standard initialization of this activity.  Set up the UI, then wait
+         * for the user to poke it before doing anything.
+         */
+        @Override
+        protected void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+
+            setContentView(R.layout.remote_binding_options);
+
+            // Watch for button clicks.
+            Button button = (Button)findViewById(R.id.bind_normal);
+            button.setOnClickListener(mBindNormalListener);
+            button = (Button)findViewById(R.id.bind_not_foreground);
+            button.setOnClickListener(mBindNotForegroundListener);
+            button = (Button)findViewById(R.id.bind_above_client);
+            button.setOnClickListener(mBindAboveClientListener);
+            button = (Button)findViewById(R.id.bind_allow_oom);
+            button.setOnClickListener(mBindAllowOomListener);
+            button = (Button)findViewById(R.id.bind_waive_priority);
+            button.setOnClickListener(mBindWaivePriorityListener);
+            button = (Button)findViewById(R.id.bind_important);
+            button.setOnClickListener(mBindImportantListener);
+            button = (Button)findViewById(R.id.bind_with_activity);
+            button.setOnClickListener(mBindWithActivityListener);
+            button = (Button)findViewById(R.id.unbind);
+            button.setOnClickListener(mUnbindListener);
+
+            mCallbackText = (TextView)findViewById(R.id.callback);
+            mCallbackText.setText("Not attached.");
+        }
+
+        private OnClickListener mBindNormalListener = new OnClickListener() {
+            public void onClick(View v) {
+                if (mCurConnection != null) {
+                    unbindService(mCurConnection);
+                    mCurConnection = null;
+                }
+                ServiceConnection conn = new MyServiceConnection();
+                if (bindService(new Intent(IRemoteService.class.getName()),
+                        conn, Context.BIND_AUTO_CREATE)) {
+                    mCurConnection = conn;
+                }
+            }
+        };
+
+        private OnClickListener mBindNotForegroundListener = new OnClickListener() {
+            public void onClick(View v) {
+                if (mCurConnection != null) {
+                    unbindService(mCurConnection);
+                    mCurConnection = null;
+                }
+                ServiceConnection conn = new MyServiceConnection();
+                if (bindService(new Intent(IRemoteService.class.getName()),
+                        conn, Context.BIND_AUTO_CREATE | Context.BIND_NOT_FOREGROUND)) {
+                    mCurConnection = conn;
+                }
+            }
+        };
+
+        private OnClickListener mBindAboveClientListener = new OnClickListener() {
+            public void onClick(View v) {
+                if (mCurConnection != null) {
+                    unbindService(mCurConnection);
+                    mCurConnection = null;
+                }
+                ServiceConnection conn = new MyServiceConnection();
+                if (bindService(new Intent(IRemoteService.class.getName()),
+                        conn, Context.BIND_AUTO_CREATE | Context.BIND_ABOVE_CLIENT)) {
+                    mCurConnection = conn;
+                }
+            }
+        };
+
+        private OnClickListener mBindAllowOomListener = new OnClickListener() {
+            public void onClick(View v) {
+                if (mCurConnection != null) {
+                    unbindService(mCurConnection);
+                    mCurConnection = null;
+                }
+                ServiceConnection conn = new MyServiceConnection();
+                if (bindService(new Intent(IRemoteService.class.getName()),
+                        conn, Context.BIND_AUTO_CREATE | Context.BIND_ALLOW_OOM_MANAGEMENT)) {
+                    mCurConnection = conn;
+                }
+            }
+        };
+
+        private OnClickListener mBindWaivePriorityListener = new OnClickListener() {
+            public void onClick(View v) {
+                if (mCurConnection != null) {
+                    unbindService(mCurConnection);
+                    mCurConnection = null;
+                }
+                ServiceConnection conn = new MyServiceConnection(true);
+                if (bindService(new Intent(IRemoteService.class.getName()),
+                        conn, Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY)) {
+                    mCurConnection = conn;
+                }
+            }
+        };
+
+        private OnClickListener mBindImportantListener = new OnClickListener() {
+            public void onClick(View v) {
+                if (mCurConnection != null) {
+                    unbindService(mCurConnection);
+                    mCurConnection = null;
+                }
+                ServiceConnection conn = new MyServiceConnection();
+                if (bindService(new Intent(IRemoteService.class.getName()),
+                        conn, Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT)) {
+                    mCurConnection = conn;
+                }
+            }
+        };
+
+        private OnClickListener mBindWithActivityListener = new OnClickListener() {
+            public void onClick(View v) {
+                if (mCurConnection != null) {
+                    unbindService(mCurConnection);
+                    mCurConnection = null;
+                }
+                ServiceConnection conn = new MyServiceConnection();
+                if (bindService(new Intent(IRemoteService.class.getName()),
+                        conn, Context.BIND_AUTO_CREATE | Context.BIND_ADJUST_WITH_ACTIVITY
+                        | Context.BIND_WAIVE_PRIORITY)) {
+                    mCurConnection = conn;
+                }
+            }
+        };
+
+        private OnClickListener mUnbindListener = new OnClickListener() {
+            public void onClick(View v) {
+                if (mCurConnection != null) {
+                    unbindService(mCurConnection);
+                    mCurConnection = null;
+                }
+            }
+        };
+    }
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/_index.html b/samples/ApiDemos/src/com/example/android/apis/app/_index.html
index e9d1cf5..4333d57 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/_index.html
+++ b/samples/ApiDemos/src/com/example/android/apis/app/_index.html
@@ -101,6 +101,10 @@
   <dd>Demonstrates how to display and respond to a context menu that is
   display from a fragment's view hierarchy.</dd>
   
+  <dt><a href="FragmentCustomAnimation.html">Fragment Custom Animation</a></dt>
+  <dd>Demonstrates the use of a custom animation for pushing and popping fragments
+  on the back stack.</dd>
+
   <dt><a href="FragmentDialog.html">Fragment Dialog</a></dt>
   <dd>Demonstrates use of DialogFragment to show various types of dialogs.</dd>
   
@@ -156,6 +160,10 @@
 default Honeycomb theme includes the Action Bar by default and a menu resource is used to populate
 the menu data itself. If you'd like to see how these things work under the hood, see
 Mechanics.</dd>
+  <dt><a href="ActionBarActionProviderActivity.html">ActionProvider</a></dt>
+  <dd>Shows how to use an ActionProvider to supply a menu item with a specialized action view and
+  handle standard menu item clicks in one place. Demonstrated using the streamlined sharing UI
+  added in ICS. </dd>
   <dt><a href="ActionBarDisplayOptions.html">Display Options</a></dt>
   <dd>Shows how various Action Bar display option flags can be combined and their effects.</dd>
 </dl>
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.java b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.java
index 7488fcc..8ffa3b9 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewActionBar.java
@@ -25,8 +25,10 @@
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuInflater;
+import android.view.MenuItem;
 import android.view.View;
 import android.view.Window;
+import android.view.MenuItem.OnActionExpandListener;
 import android.widget.Button;
 import android.widget.SearchView;
 import android.widget.TextView;
@@ -65,15 +67,21 @@
 
         MenuInflater inflater = getMenuInflater();
         inflater.inflate(R.menu.searchview_in_menu, menu);
-        mSearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
-        setupSearchView();
+        MenuItem searchItem = menu.findItem(R.id.action_search);
+        mSearchView = (SearchView) searchItem.getActionView();
+        setupSearchView(searchItem);
 
         return true;
     }
 
-    private void setupSearchView() {
+    private void setupSearchView(MenuItem searchItem) {
 
-        mSearchView.setIconifiedByDefault(true);
+        if (isAlwaysExpanded()) {
+            mSearchView.setIconifiedByDefault(false);
+        } else {
+            searchItem.setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM
+                    | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
+        }
 
         SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
         if (searchManager != null) {
@@ -116,4 +124,8 @@
             mSearchView.setIconified(false);
         }
     }
+
+    protected boolean isAlwaysExpanded() {
+        return false;
+    }
 }
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/SearchViewAlwaysVisible.java b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewAlwaysVisible.java
new file mode 100644
index 0000000..8c67563
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/SearchViewAlwaysVisible.java
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.SearchManager;
+import android.app.SearchableInfo;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.SearchView;
+import android.widget.TextView;
+
+import java.util.List;
+
+/**
+ * This demonstrates the usage of SearchView in an ActionBar as a menu item.
+ * It sets a SearchableInfo on the SearchView for suggestions and submitting queries to.
+ */
+public class SearchViewAlwaysVisible extends SearchViewActionBar {
+
+    @Override
+    protected boolean isAlwaysExpanded() {
+        return true;
+    }
+}
diff --git a/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rs b/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rs
index f94e3e2..d61557c 100644
--- a/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rs
+++ b/samples/RenderScript/Balls/src/com/example/android/rs/balls/balls.rs
@@ -68,7 +68,7 @@
     bc.dimX = rsAllocationGetDimX(bc.ain);
     bc.dt = 1.f / 30.f;
 
-    rsForEach(physics_script, bc.ain, bc.aout, &bc);
+    rsForEach(physics_script, bc.ain, bc.aout, &bc, sizeof(bc));
 
     for (uint32_t ct=0; ct < bc.dimX; ct++) {
         point[ct].position = bout[ct].position;
diff --git a/samples/SampleSyncAdapter/AndroidManifest.xml b/samples/SampleSyncAdapter/AndroidManifest.xml
index fd53a16..ec8b779 100644
--- a/samples/SampleSyncAdapter/AndroidManifest.xml
+++ b/samples/SampleSyncAdapter/AndroidManifest.xml
@@ -47,7 +47,7 @@
         android:name="android.permission.WRITE_SYNC_SETTINGS" />
 
     <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11"/>
-        
+
     <application
         android:icon="@drawable/icon"
         android:label="@string/label">
@@ -112,6 +112,16 @@
                 <data
                     android:mimeType="vnd.android.cursor.item/raw_contact" />
             </intent-filter>
+            <!--
+                We use the INVITE intent to add a raw contact to an existing contact.
+                It always comes with a lookup URI.
+            -->
+            <intent-filter>
+                <action
+                    android:name="com.android.contacts.action.INVITE_CONTACT" />
+                <data
+                    android:mimeType="vnd.android.cursor.item/contact" />
+            </intent-filter>
         </activity>
     </application>
 </manifest>
diff --git a/samples/SampleSyncAdapter/res/values/strings.xml b/samples/SampleSyncAdapter/res/values/strings.xml
index 3b5ac58..7ac95f5 100644
--- a/samples/SampleSyncAdapter/res/values/strings.xml
+++ b/samples/SampleSyncAdapter/res/values/strings.xml
@@ -102,4 +102,11 @@
         name="menu_done">Done</string>
     <string
         name="menu_cancel">Cancel</string>
+
+    <!-- Strings for contacts.xml -->
+    <skip />
+
+    <!-- The label of the button to add contact to this contact provider  -->
+    <string name="invite_action_label">Add to Sample SyncAdaper</string>
+
 </resources>
\ No newline at end of file
diff --git a/samples/SampleSyncAdapter/res/xml-v14/contacts.xml b/samples/SampleSyncAdapter/res/xml-v14/contacts.xml
new file mode 100644
index 0000000..09b9e8f
--- /dev/null
+++ b/samples/SampleSyncAdapter/res/xml-v14/contacts.xml
@@ -0,0 +1,35 @@
+<?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.
+ */
+-->
+
+<ContactsAccountType
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
+    createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
+    inviteContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
+    inviteContactActionLabel="@string/invite_action_label"
+>
+
+    <ContactsDataKind
+        android:mimeType="vnd.android.cursor.item/vnd.samplesyncadapter.profile"
+        android:icon="@drawable/icon"
+        android:summaryColumn="data2"
+        android:detailColumn="data3"
+        android:detailSocialSummary="true" />
+
+</ContactsAccountType>
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/editor/ContactEditorActivity.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/editor/ContactEditorActivity.java
index 2e30be7..efda0cc 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/editor/ContactEditorActivity.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/editor/ContactEditorActivity.java
@@ -15,12 +15,16 @@
  */
 package com.example.android.samplesync.editor;
 
+import com.example.android.samplesync.Constants;
 import com.example.android.samplesync.R;
 import com.example.android.samplesync.client.RawContact;
 import com.example.android.samplesync.platform.BatchOperation;
 import com.example.android.samplesync.platform.ContactManager;
+import com.example.android.samplesync.platform.ContactManager.ContactQuery;
 import com.example.android.samplesync.platform.ContactManager.EditorQuery;
 
+import android.accounts.Account;
+import android.accounts.AccountManager;
 import android.app.Activity;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -29,6 +33,7 @@
 import android.net.Uri;
 import android.os.AsyncTask;
 import android.os.Bundle;
+import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Email;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
@@ -86,8 +91,8 @@
         mWorkPhoneEditText = (EditText)findViewById(R.id.editor_phone_work);
         mEmailEditText = (EditText)findViewById(R.id.editor_email);
 
-        // Figure out whether we're creating a new contact (ACTION_INSERT) or editing
-        // an existing contact.
+        // Figure out whether we're creating a new contact (ACTION_INSERT), editing
+        // an existing contact, or adding a new one to existing contact (INVITE_CONTACT).
         Intent intent = getIntent();
         String action = intent.getAction();
         if (Intent.ACTION_INSERT.equals(action)) {
@@ -100,6 +105,24 @@
                 finish();
             }
             setAccountName(accountName);
+        } else if (ContactsContract.Intents.INVITE_CONTACT.equals(action)) {
+            // Adding to an existing contact.
+            mIsInsert = true;
+            // Use the first account found.
+            Account[] myAccounts = AccountManager.get(this).getAccountsByType(
+                    Constants.ACCOUNT_TYPE);
+            if (myAccounts.length == 0) {
+                Log.e(TAG, "Account not configured");
+                finish();
+            }
+            setAccountName(myAccounts[0].name);
+
+            Uri lookupUri = intent.getData();
+            if (lookupUri == null) {
+                Log.e(TAG, "Contact lookup URI is required");
+                finish();
+            }
+            startLoadContactEntity(lookupUri);
         } else {
             // We're editing an existing contact. Load in the data from the contact
             // so that the user can edit it.
@@ -163,7 +186,7 @@
      * successfully loaded from the Contacts data provider.
      */
     public void onRawContactEntityLoaded(Cursor cursor) {
-        while (cursor.moveToNext()) {
+        if (cursor.moveToFirst()) {
             String mimetype = cursor.getString(EditorQuery.COLUMN_MIMETYPE);
             if (StructuredName.CONTENT_ITEM_TYPE.equals(mimetype)) {
                 setAccountName(cursor.getString(EditorQuery.COLUMN_ACCOUNT_NAME));
@@ -185,6 +208,23 @@
     }
 
     /**
+     * Create an AsyncTask to load the contact from the Contacts data provider
+     */
+    private void startLoadContactEntity(Uri lookupUri) {
+        new LoadContactTask().execute(lookupUri);
+    }
+
+    /**
+     * Called by the LoadContactTask when the contact information has been
+     * successfully loaded from the Contacts data provider.
+     */
+    public void onContactEntityLoaded(Cursor cursor) {
+        if (cursor.moveToFirst()) {
+            mNameEditText.setText(cursor.getString(ContactQuery.COLUMN_DISPLAY_NAME));
+        }
+    }
+
+    /**
      * Save the updated contact data. We actually take two different actions
      * depending on whether we are creating a new contact or editing an
      * existing contact.
@@ -212,6 +252,7 @@
      */
     private void setAccountName(String accountName) {
         mAccountName = accountName;
+        Log.i(TAG, "account=" + mAccountName);
         if (accountName != null) {
             TextView accountNameLabel = (TextView)findViewById(R.id.header_account_name);
             if (accountNameLabel != null) {
@@ -286,12 +327,11 @@
 
         @Override
         protected void onPostExecute(Cursor cursor) {
+            if (cursor == null) return;
             // After we've successfully loaded the contact, call back into
             // the ContactEditorActivity so we can update the UI
             try {
-                if (cursor != null) {
-                    onRawContactEntityLoaded(cursor);
-                }
+                onRawContactEntityLoaded(cursor);
             } finally {
                 cursor.close();
             }
@@ -366,4 +406,25 @@
             onContactSaved(result);
         }
     }
+
+    /**
+     * Loads contact information by a lookup URI.
+     */
+    public class LoadContactTask extends AsyncTask<Uri, Void, Cursor> {
+
+        @Override
+        protected Cursor doInBackground(Uri... params) {
+            return getContentResolver().query(params[0], ContactQuery.PROJECTION, null, null, null);
+        }
+
+        @Override
+        protected void onPostExecute(Cursor cursor) {
+            if (cursor == null) return;
+            try {
+                onContactEntityLoaded(cursor);
+            } finally {
+                cursor.close();
+            }
+        }
+    }
 }
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
index 2335d38..035c976 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
@@ -32,6 +32,7 @@
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
+import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.Settings;
@@ -751,4 +752,18 @@
 
         public static final String SELECTION = Data.RAW_CONTACT_ID + "=?";
     }
+
+    /**
+     * Constants for a query to read basic contact columns
+     */
+    final public static class ContactQuery {
+        private ContactQuery() {
+        }
+
+        public static final String[] PROJECTION =
+            new String[] {Contacts._ID, Contacts.DISPLAY_NAME};
+
+        public static final int COLUMN_ID = 0;
+        public static final int COLUMN_DISPLAY_NAME = 1;
+    }
 }
diff --git a/samples/Support4Demos/AndroidManifest.xml b/samples/Support4Demos/AndroidManifest.xml
index 4719268..6a05b73 100644
--- a/samples/Support4Demos/AndroidManifest.xml
+++ b/samples/Support4Demos/AndroidManifest.xml
@@ -67,6 +67,14 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".app.FragmentCustomAnimationSupport"
+                android:label="@string/fragment_custom_animation_support">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.example.android.supportv4.SUPPORT4_SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".app.FragmentHideShowSupport"
                 android:label="@string/fragment_hide_show_support"
                 android:windowSoftInputMode="stateUnchanged">
diff --git a/samples/Support4Demos/res/anim/decelerate_quint.xml b/samples/Support4Demos/res/anim/decelerate_quint.xml
new file mode 100644
index 0000000..ff2d5a9
--- /dev/null
+++ b/samples/Support4Demos/res/anim/decelerate_quint.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2010, 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.
+*/
+-->
+
+<decelerateInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+        android:factor="2.5" />
diff --git a/samples/Support4Demos/res/anim/fragment_slide_left_enter.xml b/samples/Support4Demos/res/anim/fragment_slide_left_enter.xml
new file mode 100644
index 0000000..6bbf6a2
--- /dev/null
+++ b/samples/Support4Demos/res/anim/fragment_slide_left_enter.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_quint">
+    <translate android:fromXDelta="33%" android:toXDelta="0%p"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+            android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/Support4Demos/res/anim/fragment_slide_left_exit.xml b/samples/Support4Demos/res/anim/fragment_slide_left_exit.xml
new file mode 100644
index 0000000..0affbc7
--- /dev/null
+++ b/samples/Support4Demos/res/anim/fragment_slide_left_exit.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_quint">
+    <translate android:fromXDelta="0%" android:toXDelta="-33%p"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+            android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/Support4Demos/res/anim/fragment_slide_right_enter.xml b/samples/Support4Demos/res/anim/fragment_slide_right_enter.xml
new file mode 100644
index 0000000..e2e1168
--- /dev/null
+++ b/samples/Support4Demos/res/anim/fragment_slide_right_enter.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_quint">
+    <translate android:fromXDelta="-33%" android:toXDelta="0%p"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+            android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/Support4Demos/res/anim/fragment_slide_right_exit.xml b/samples/Support4Demos/res/anim/fragment_slide_right_exit.xml
new file mode 100644
index 0000000..c8e6e7c
--- /dev/null
+++ b/samples/Support4Demos/res/anim/fragment_slide_right_exit.xml
@@ -0,0 +1,23 @@
+<?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.
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_quint">
+    <translate android:fromXDelta="0%" android:toXDelta="33%p"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+    <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
+            android:duration="@android:integer/config_mediumAnimTime" />
+</set>
diff --git a/samples/Support4Demos/res/values/strings.xml b/samples/Support4Demos/res/values/strings.xml
index 5fa5af7..4e8d9de 100644
--- a/samples/Support4Demos/res/values/strings.xml
+++ b/samples/Support4Demos/res/values/strings.xml
@@ -41,6 +41,8 @@
     <string name="fragment_arguments_embedded">From Attributes</string>
     <string name="fragment_arguments_embedded_land">Landscape Only</string>
 
+    <string name="fragment_custom_animation_support">Fragment/Custom Animation</string>
+
     <string name="fragment_hide_show_support">Fragment/Hide and Show</string>
 
     <string name="fragment_context_menu_support">Fragment/Context Menu</string>
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentCustomAnimationSupport.java b/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentCustomAnimationSupport.java
new file mode 100644
index 0000000..5893521
--- /dev/null
+++ b/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentCustomAnimationSupport.java
@@ -0,0 +1,128 @@
+/*
+ * 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.
+ */
+
+package com.example.android.supportv4.app;
+
+import com.example.android.supportv4.R;
+
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.app.FragmentTransaction;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+public class FragmentCustomAnimationSupport extends FragmentActivity {
+    int mStackLevel = 1;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.fragment_stack);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.new_fragment);
+        button.setOnClickListener(new OnClickListener() {
+            public void onClick(View v) {
+                addFragmentToStack();
+            }
+        });
+
+        if (savedInstanceState == null) {
+            // Do first time initialization -- add initial fragment.
+            Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+            ft.add(R.id.simple_fragment, newFragment).commit();
+        } else {
+            mStackLevel = savedInstanceState.getInt("level");
+        }
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt("level", mStackLevel);
+    }
+
+//BEGIN_INCLUDE(add_stack)
+    void addFragmentToStack() {
+        mStackLevel++;
+
+        // Instantiate a new fragment.
+        Fragment newFragment = CountingFragment.newInstance(mStackLevel);
+
+        // Add the fragment to the activity, pushing this transaction
+        // on to the back stack.
+        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+        ft.setCustomAnimations(R.anim.fragment_slide_left_enter,
+                R.anim.fragment_slide_left_exit,
+                R.anim.fragment_slide_right_enter,
+                R.anim.fragment_slide_right_exit);
+        ft.replace(R.id.simple_fragment, newFragment);
+        ft.addToBackStack(null);
+        ft.commit();
+    }
+//END_INCLUDE(add_stack)
+
+//BEGIN_INCLUDE(fragment)
+    public static class CountingFragment extends Fragment {
+        int mNum;
+
+        /**
+         * Create a new instance of CountingFragment, providing "num"
+         * as an argument.
+         */
+        static CountingFragment newInstance(int num) {
+            CountingFragment f = new CountingFragment();
+
+            // Supply num input as an argument.
+            Bundle args = new Bundle();
+            args.putInt("num", num);
+            f.setArguments(args);
+
+            return f;
+        }
+
+        /**
+         * When creating, retrieve this instance's number from its arguments.
+         */
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+            super.onCreate(savedInstanceState);
+            mNum = getArguments() != null ? getArguments().getInt("num") : 1;
+        }
+
+        /**
+         * The Fragment's UI is just a simple text view showing its
+         * instance number.
+         */
+        @Override
+        public View onCreateView(LayoutInflater inflater, ViewGroup container,
+                Bundle savedInstanceState) {
+            View v = inflater.inflate(R.layout.hello_world, container, false);
+            View tv = v.findViewById(R.id.text);
+            ((TextView)tv).setText("Fragment #" + mNum);
+            tv.setBackgroundDrawable(getResources().getDrawable(android.R.drawable.gallery_thumb));
+            return v;
+        }
+    }
+//END_INCLUDE(fragment)
+}
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/app/_index.html b/samples/Support4Demos/src/com/example/android/supportv4/app/_index.html
index fa9af5a..d203ffb 100644
--- a/samples/Support4Demos/src/com/example/android/supportv4/app/_index.html
+++ b/samples/Support4Demos/src/com/example/android/supportv4/app/_index.html
@@ -23,6 +23,10 @@
   <dd>Demonstrates how to display and respond to a context menu that is
   display from a fragment's view hierarchy.</dd>
   
+  <dt><a href="FragmentCustomAnimationSupport.html">Fragment Custom Animation</a></dt>
+  <dd>Demonstrates the use of a custom animation for pushing and popping fragments
+  on the back stack.</dd>
+
   <dt><a href="FragmentDialogSupport.html">Fragment Dialog</a></dt>
   <dd>Demonstrates use of DialogFragment to show various types of dialogs.</dd>