resolved conflicts for merge of 9eecf3fc to master

Change-Id: If38c80cd560d8b419420fc05a872c31b6031d90a
diff --git a/apps/Development/res/layout/connectivity.xml b/apps/Development/res/layout/connectivity.xml
index 53f1ed7..a3a3dcf 100644
--- a/apps/Development/res/layout/connectivity.xml
+++ b/apps/Development/res/layout/connectivity.xml
@@ -219,6 +219,15 @@
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@string/start_tdls" />
+        <Button android:id="@+id/stopTdls"
+          android:layout_width="wrap_content"
+          android:layout_height="wrap_content"
+          android:text="@string/stop_tdls" />
+    </LinearLayout>
+    <LinearLayout
+      android:orientation="horizontal"
+      android:layout_width="match_parent"
+      android:layout_height="wrap_content">
         <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
@@ -227,10 +236,6 @@
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:minEms="10" />
-        <Button android:id="@+id/stopTdls"
-          android:layout_width="wrap_content"
-          android:layout_height="wrap_content"
-          android:text="@string/stop_tdls" />
     </LinearLayout>
 
     <!-- divider line -->
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-az-rAZ/strings.xml
similarity index 70%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-az-rAZ/strings.xml
index d59ae53..8e1956a 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-az-rAZ/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"Son çarə"</string>
+    <string name="title" msgid="8156274565006125136">"Dəstəklənməyən fəaliyyət"</string>
+    <string name="error" msgid="6539615832923362301">"Bu fəaliyyət hazırda dəstəklənmir."</string>
 </resources>
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-az/strings.xml
similarity index 70%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-az/strings.xml
index d59ae53..8e1956a 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-az/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"Son çarə"</string>
+    <string name="title" msgid="8156274565006125136">"Dəstəklənməyən fəaliyyət"</string>
+    <string name="error" msgid="6539615832923362301">"Bu fəaliyyət hazırda dəstəklənmir."</string>
 </resources>
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-en-rIN/strings.xml
similarity index 70%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-en-rIN/strings.xml
index d59ae53..a7c82cb 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-en-rIN/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"Unsupported action"</string>
+    <string name="error" msgid="6539615832923362301">"That action is not currently supported."</string>
 </resources>
diff --git a/apps/Fallback/res/values-et/strings.xml b/apps/Fallback/res/values-et-rEE/strings.xml
similarity index 100%
rename from apps/Fallback/res/values-et/strings.xml
rename to apps/Fallback/res/values-et-rEE/strings.xml
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-fr-rCA/strings.xml
similarity index 70%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-fr-rCA/strings.xml
index d59ae53..a751b97 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-fr-rCA/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"Application de secours"</string>
+    <string name="title" msgid="8156274565006125136">"Action non prise en charge"</string>
+    <string name="error" msgid="6539615832923362301">"Cette action n\'est actuellement pas prise en charge."</string>
 </resources>
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-hy-rAM/strings.xml
similarity index 70%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-hy-rAM/strings.xml
index d59ae53..1547741 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-hy-rAM/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"Չաջակցվող գործողություն"</string>
+    <string name="error" msgid="6539615832923362301">"Այդ գործողությունն այժմ չի աջակցվում:"</string>
 </resources>
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-ka-rGE/strings.xml
similarity index 65%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-ka-rGE/strings.xml
index d59ae53..469a135 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-ka-rGE/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"შემოვლით რეჟიმში გადასვლა"</string>
+    <string name="title" msgid="8156274565006125136">"მოქმედება მხარდაჭერილი არ არის"</string>
+    <string name="error" msgid="6539615832923362301">"ეს მოქმედება ამჟამად მხარდაუჭერელია."</string>
 </resources>
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-km-rKH/strings.xml
similarity index 66%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-km-rKH/strings.xml
index d59ae53..a442335 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-km-rKH/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"សកម្មភាព​មិន​បាន​គាំទ្រ"</string>
+    <string name="error" msgid="6539615832923362301">"បច្ចុប្បន្ន​សកម្មភាព​នោះ​មិន​ត្រូវ​បាន​គាំទ្រ​ទេ។"</string>
 </resources>
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-lo-rLA/strings.xml
similarity index 69%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-lo-rLA/strings.xml
index d59ae53..948b60f 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-lo-rLA/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"ການເຮັດວຽກທີ່ບໍ່ຮອງຮັບ"</string>
+    <string name="error" msgid="6539615832923362301">"ການເຮັດວຽກນັ້ນຍັງບໍ່ຮອງຮັບເທື່ອ"</string>
 </resources>
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-mn-rMN/strings.xml
similarity index 70%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-mn-rMN/strings.xml
index d59ae53..8cb3870 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-mn-rMN/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"Дэмжигдээгүй үйлдэл"</string>
+    <string name="error" msgid="6539615832923362301">"Энэ үйлдэл одоогоор дэмжигдээгүй."</string>
 </resources>
diff --git a/apps/Fallback/res/values-ms/strings.xml b/apps/Fallback/res/values-ms-rMY/strings.xml
similarity index 100%
rename from apps/Fallback/res/values-ms/strings.xml
rename to apps/Fallback/res/values-ms-rMY/strings.xml
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-ne-rNP/strings.xml
similarity index 71%
rename from apps/Fallback/res/values-be/strings.xml
rename to apps/Fallback/res/values-ne-rNP/strings.xml
index d59ae53..7d27eff 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-ne-rNP/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"असमर्थित कार्य"</string>
+    <string name="error" msgid="6539615832923362301">"यस कारवाही हाल समर्थित छैन।"</string>
 </resources>
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-ne/strings.xml
similarity index 71%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-ne/strings.xml
index d59ae53..7d27eff 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-ne/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"असमर्थित कार्य"</string>
+    <string name="error" msgid="6539615832923362301">"यस कारवाही हाल समर्थित छैन।"</string>
 </resources>
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-si-rLK/strings.xml
similarity index 69%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-si-rLK/strings.xml
index d59ae53..8a7e7a5 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-si-rLK/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"පසු බැසීම"</string>
+    <string name="title" msgid="8156274565006125136">"සහය නොදක්වන ක්‍රියාව"</string>
+    <string name="error" msgid="6539615832923362301">"එම ක්‍රියාවට දැන් සහය නොදක්වයි."</string>
 </resources>
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-si/strings.xml
similarity index 69%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-si/strings.xml
index d59ae53..8a7e7a5 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-si/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"පසු බැසීම"</string>
+    <string name="title" msgid="8156274565006125136">"සහය නොදක්වන ක්‍රියාව"</string>
+    <string name="error" msgid="6539615832923362301">"එම ක්‍රියාවට දැන් සහය නොදක්වයි."</string>
 </resources>
diff --git a/apps/Fallback/res/values-be/strings.xml b/apps/Fallback/res/values-zh-rHK/strings.xml
similarity index 70%
copy from apps/Fallback/res/values-be/strings.xml
copy to apps/Fallback/res/values-zh-rHK/strings.xml
index d59ae53..ce01c92 100644
--- a/apps/Fallback/res/values-be/strings.xml
+++ b/apps/Fallback/res/values-zh-rHK/strings.xml
@@ -16,7 +16,7 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="appTitle" msgid="161410001913116606">"Дапаможны"</string>
-    <string name="title" msgid="8156274565006125136">"Дзеянні, якія не падрымліваюцца"</string>
-    <string name="error" msgid="6539615832923362301">"Гэтае дзеянне зараз не падтрымліваецца."</string>
+    <string name="appTitle" msgid="161410001913116606">"後備"</string>
+    <string name="title" msgid="8156274565006125136">"不支援的操作"</string>
+    <string name="error" msgid="6539615832923362301">"目前不支援該操作。"</string>
 </resources>
diff --git a/build/Android.mk b/build/Android.mk
index fb34734..cb2dcfb 100644
--- a/build/Android.mk
+++ b/build/Android.mk
@@ -125,6 +125,8 @@
     android-support-v7-mediarouter \
     android-support-v7-recyclerview \
     android-support-v13 \
-    android-support-v17-leanback
+    android-support-v17-leanback \
+    android-support-multidex \
+    android-support-multidex-instrumentation
 
 $(foreach lib, $(ANDROID_SUPPORT_LIBRARIES), $(eval $(call _package_sdk_library,$(lib))))
diff --git a/build/sdk.atree b/build/sdk.atree
index c1fcebc..a91891c 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -359,6 +359,25 @@
 ${OUT_DIR}/target/common/obj/PACKAGING/android-support-v7-appcompat_intermediates/android-support-v7-appcompat.jar    extras/android/support/v7/appcompat/libs/android-support-v7-appcompat.jar
 ${OUT_DIR}/target/common/obj/PACKAGING/android-support-v4_intermediates/android-support-v4.jar                        extras/android/support/v7/appcompat/libs/android-support-v4.jar
 
+frameworks/multidex/library/README.txt                                                            extras/android/support/multidex/library/README.txt
+frameworks/multidex/library/.project                                                              extras/android/support/multidex/library/.project
+frameworks/multidex/library/.classpath                                                            extras/android/support/multidex/library/.classpath
+frameworks/multidex/library/AndroidManifest.xml                                                   extras/android/support/multidex/library/AndroidManifest.xml
+frameworks/multidex/library/project.properties                                                    extras/android/support/multidex/library/project.properties
+frameworks/multidex/library/src/.readme                                                           extras/android/support/multidex/library/src/.readme
+frameworks/multidex/library/res/.readme                                                           extras/android/support/multidex/library/res/.readme
+${OUT_DIR}/target/common/obj/PACKAGING/android-support-multidex_intermediates/android-support-multidex.jar              extras/android/support/multidex/library/libs/android-support-multidex.jar
+
+frameworks/multidex/instrumentation/README.txt                                                         extras/android/support/multidex/instrumentation/README.txt
+frameworks/multidex/instrumentation/.project                                                           extras/android/support/multidex/instrumentation/.project
+frameworks/multidex/instrumentation/.classpath                                                         extras/android/support/multidex/instrumentation/.classpath
+frameworks/multidex/instrumentation/AndroidManifest.xml                                                extras/android/support/multidex/instrumentation/AndroidManifest.xml
+frameworks/multidex/instrumentation/project.properties                                                 extras/android/support/multidex/instrumentation/project.properties
+frameworks/multidex/instrumentation/src/.readme                                                        extras/android/support/multidex/instrumentation/src/.readme
+frameworks/multidex/instrumentation/res/.readme                                                        extras/android/support/multidex/instrumentation/res/.readme
+${OUT_DIR}/target/common/obj/PACKAGING/android-support-multidex-instrumentation_intermediates/android-support-multidex-instrumentation.jar      extras/android/support/multidex/instrumentation/libs/android-support-multidex-instrumentation.jar
+${OUT_DIR}/target/common/obj/PACKAGING/android-support-multidex_intermediates/android-support-multidex.jar                                      extras/android/support/multidex/instrumentation/libs/android-support-multidex.jar
+
 frameworks/support/v7/mediarouter/README.txt                                                       extras/android/support/v7/mediarouter/README.txt
 frameworks/support/v7/mediarouter/.project                                                         extras/android/support/v7/mediarouter/.project
 frameworks/support/v7/mediarouter/.classpath                                                       extras/android/support/v7/mediarouter/.classpath
@@ -387,6 +406,5 @@
 # Tests Component
 ##############################################################################
 framework/layoutlib-tests.jar tests/libtests/layoutlib-tests.jar
-system/app/ConnectivityTest.apk tests/emulator-test-apps/ConnectivityTest.apk
-system/app/GpsLocationTest.apk tests/emulator-test-apps/GpsLocationTest.apk
+system/app/EmulatorSmokeTests.apk tests/emulator-test-apps/EmulatorSmokeTests.apk
 
diff --git a/build/windows_sdk_whitelist.mk b/build/windows_sdk_whitelist.mk
index 548e6fd..c89d7a9 100644
--- a/build/windows_sdk_whitelist.mk
+++ b/build/windows_sdk_whitelist.mk
@@ -48,6 +48,7 @@
 	frameworks/compile \
 	frameworks/native \
 	frameworks/rs \
+	frameworks/tools \
 	system/core/adb \
 	system/core/fastboot \
 	system/core/libcutils \
diff --git a/ide/eclipse/.classpath b/ide/eclipse/.classpath
index af99325..2da7f58 100644
--- a/ide/eclipse/.classpath
+++ b/ide/eclipse/.classpath
@@ -64,6 +64,7 @@
 	<classpathentry kind="src" path="frameworks/base/packages/SettingsProvider/src"/>
 	<classpathentry kind="src" path="frameworks/base/packages/SystemUI/src"/>
 	<classpathentry kind="src" path="frameworks/base/policy/src"/>
+	<classpathentry kind="src" path="frameworks/base/rs/java"/>
 	<classpathentry kind="src" path="frameworks/base/sax/java"/>
 	<classpathentry kind="src" path="frameworks/base/services/core/java"/>
         <classpathentry kind="src" path="frameworks/base/services/accessibility/java"/>
@@ -84,6 +85,7 @@
 	<classpathentry kind="src" path="frameworks/opt/telephony/src/java"/>
 	<classpathentry kind="src" path="frameworks/opt/mms/src/java"/>
 	<classpathentry kind="src" path="frameworks/opt/net/voip/src/java"/>
+	<classpathentry kind="src" path="frameworks/opt/net/wifi/service/java"/>
 	<classpathentry kind="src" path="frameworks/opt/vcard/java"/>
 	<classpathentry kind="src" path="frameworks/support/renderscript/v8/java/src"/>
 	<classpathentry kind="src" path="frameworks/support/v13/java"/>
diff --git a/ide/eclipse/android-formatting.xml b/ide/eclipse/android-formatting.xml
index 9b43767..9c2af85 100644
--- a/ide/eclipse/android-formatting.xml
+++ b/ide/eclipse/android-formatting.xml
@@ -52,7 +52,7 @@
 <setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/>
 <setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/>
 <setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
-<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="80"/>
+<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="100"/>
 <setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
 <setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
 <setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index f202d59..a21b23c 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -37,7 +37,7 @@
     <!-- For android.media.audiofx.Visualizer -->
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
 
-    <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="17" />
+    <uses-sdk android:minSdkVersion="4" android:targetSdkVersion="19" />
 
     <!-- We will request access to the camera, saying we require a camera
          of some sort but not one with autofocus capability. -->
@@ -48,6 +48,7 @@
     <application android:name="ApiDemosApplication"
             android:label="@string/activity_sample_code"
             android:icon="@drawable/app_sample_code"
+            android:theme="@style/ThemeCurrent"
             android:hardwareAccelerated="true"
             android:supportsRtl="true">
 
@@ -78,7 +79,7 @@
 
         <activity android:name=".app.DialogActivity"
                 android:label="@string/activity_dialog"
-                android:theme="@android:style/Theme.Holo.Dialog">
+                android:theme="@style/ThemeCurrentDialog">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -740,7 +741,7 @@
 <!-- BEGIN_INCLUDE(interstitial_affinity) -->
         <activity android:name=".app.IncomingMessageInterstitial"
                 android:label="You have messages"
-                android:theme="@style/ThemeHoloDialog"
+                android:theme="@style/ThemeCurrentDialog"
                 android:launchMode="singleTask"
                 android:taskAffinity=""
                 android:excludeFromRecents="true">
@@ -1258,13 +1259,6 @@
             </intent-filter>
         </activity>
 
-        <activity android:name=".os.Sensors" android:label="OS/Sensors">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.SAMPLE_CODE" />
-            </intent-filter>
-        </activity>
-
         <activity android:name=".os.TriggerSensors" android:label="OS/TriggerSensors">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -1300,6 +1294,25 @@
         <!--     ANDROID.ANIMATION PACKAGE SAMPLES         -->
         <!-- ************************************* -->
 
+        <activity android:name=".animation.ActivityTransition"
+                android:label="Animation/Activity Transition"
+                android:enabled="@bool/atLeastHoneycomb"
+                android:theme="@style/ActivityTransitionTheme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".animation.ActivityTransitionDetails"
+                android:label="Animation/Details of a specific thingy"
+                android:enabled="@bool/atLeastHoneycomb"
+                android:theme="@style/ActivityTransitionTheme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".animation.AnimationLoading"
                 android:label="Animation/Loading"
                 android:enabled="@bool/atLeastHoneycomb">
@@ -1417,6 +1430,15 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".animation.PathAnimations"
+                  android:label="Animation/Path Animations"
+                  android:enabled="@bool/atLeastHoneycomb">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <!-- ************************************* -->
         <!--     ANIMATION PACKAGE SAMPLES         -->
         <!-- ************************************* -->
@@ -2160,8 +2182,9 @@
         </activity>
 
         <activity android:name=".view.Controls5"
-                  android:label="Views/Controls/5. Custom Theme"
-                  android:theme="@style/CustomTheme">
+                  android:label="Views/Controls/5. Quantum Light Theme"
+                  android:theme="@android:style/Theme.Quantum.Light"
+                  android:enabled="@bool/atLeastLRelease">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -2169,8 +2192,35 @@
         </activity>
 
         <activity android:name=".view.Controls6"
-                  android:label="Views/Controls/6. Holo or Old Theme"
-                  android:theme="@style/ThemeHolo">
+                  android:label="Views/Controls/6. Quantum Dark Theme"
+                  android:theme="@android:style/Theme.Quantum"
+                  android:enabled="@bool/atLeastLRelease">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Controls7"
+                  android:label="Views/Controls/7. Custom Theme"
+                  android:theme="@style/CustomTheme">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Controls8"
+                  android:label="Views/Controls/7. Current or Old Theme"
+                  android:theme="@style/ThemeCurrent">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.Controls9"
+                  android:label="Views/Controls/9. Default Theme">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.SAMPLE_CODE" />
@@ -2584,7 +2634,7 @@
 
         <activity android:name=".graphics.TriangleActivity"
                 android:label="Graphics/OpenGL ES/Textured Triangle"
-                android:theme="@android:style/Theme.Holo.Dialog"
+                android:theme="@style/ThemeCurrentDialog"
                 android:configChanges="keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/samples/ApiDemos/res/drawable-nodpi/ball.jpg b/samples/ApiDemos/res/drawable-nodpi/ball.jpg
new file mode 100644
index 0000000..2960b73
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-nodpi/ball.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-nodpi/block.jpg b/samples/ApiDemos/res/drawable-nodpi/block.jpg
new file mode 100644
index 0000000..04c22a0
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-nodpi/block.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-nodpi/ducky.jpg b/samples/ApiDemos/res/drawable-nodpi/ducky.jpg
new file mode 100644
index 0000000..830bbe3
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-nodpi/ducky.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-nodpi/jellies.jpg b/samples/ApiDemos/res/drawable-nodpi/jellies.jpg
new file mode 100644
index 0000000..ee2b5c6
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-nodpi/jellies.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-nodpi/mug.jpg b/samples/ApiDemos/res/drawable-nodpi/mug.jpg
new file mode 100644
index 0000000..e149e19
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-nodpi/mug.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-nodpi/pencil.jpg b/samples/ApiDemos/res/drawable-nodpi/pencil.jpg
new file mode 100644
index 0000000..e348311
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-nodpi/pencil.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-nodpi/scissors.jpg b/samples/ApiDemos/res/drawable-nodpi/scissors.jpg
new file mode 100644
index 0000000..caf0ce8
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-nodpi/scissors.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-nodpi/woot.jpg b/samples/ApiDemos/res/drawable-nodpi/woot.jpg
new file mode 100644
index 0000000..ccaef67
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-nodpi/woot.jpg
Binary files differ
diff --git a/samples/ApiDemos/res/layout/controls_1.xml b/samples/ApiDemos/res/layout/controls_1.xml
index e280188..cd7fd0d 100644
--- a/samples/ApiDemos/res/layout/controls_1.xml
+++ b/samples/ApiDemos/res/layout/controls_1.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2007 The Android Open Source Project
+<!--
+     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.
@@ -15,139 +16,143 @@
 -->
 
 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:orientation="vertical" >
 
     <LinearLayout
-        android:orientation="vertical"
         android:layout_width="match_parent"
-        android:layout_height="wrap_content">
+        android:layout_height="wrap_content"
+        android:orientation="vertical" >
 
-       <LinearLayout
-           android:orientation="horizontal"
-           android:layout_width="match_parent"
-           android:layout_height="wrap_content">
-
-        <Button android:id="@+id/button"
-            android:text="@string/controls_1_save"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
-
-        <Button android:id="@+id/button_disabled"
-            android:text="@string/controls_1_save"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"/>
-
-      </LinearLayout>
-
-      <LinearLayout
-        android:orientation="horizontal"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content">
-
-        <EditText android:id="@+id/edit"
+        <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
+            android:layout_height="wrap_content"
+            android:orientation="horizontal" >
 
-        <EditText android:id="@+id/edit2"
+            <Button
+                android:id="@+id/button"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/controls_1_save" />
+
+            <Button
+                android:id="@+id/button_disabled"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/controls_1_save" />
+        </LinearLayout>
+
+        <LinearLayout
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"/>
+            android:layout_height="wrap_content"
+            android:orientation="horizontal" >
 
-      </LinearLayout>
+            <EditText
+                android:id="@+id/edit"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
 
-        <CheckBox android:id="@+id/check1"
-            android:paddingBottom="24sp"
-	        android:paddingTop="24sp"
+            <EditText
+                android:id="@+id/edit2"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_weight="1" />
+        </LinearLayout>
+
+        <CheckBox
+            android:id="@+id/check1"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:paddingBottom="24sp"
+            android:paddingTop="24sp"
             android:text="@string/controls_1_checkbox_1" />
 
-        <CheckBox android:id="@+id/check2"
+        <CheckBox
+            android:id="@+id/check2"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/controls_1_checkbox_2" />
-    
+
         <RadioGroup
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:orientation="vertical">
-    
-            <RadioButton android:id="@+id/radio1"
+            android:orientation="vertical" >
+
+            <RadioButton
+                android:id="@+id/radio1"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:text="@string/controls_1_radiobutton_1" />
-    
-            <RadioButton android:id="@+id/radio2"
+
+            <RadioButton
+                android:id="@+id/radio2"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:text="@string/controls_1_radiobutton_2" />
-    
         </RadioGroup>
-    
-        <CheckBox android:id="@+id/star"
+
+        <CheckBox
+            android:id="@+id/star"
             style="?android:attr/starStyle"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:text="@string/controls_1_star" />
-                            
-        <ToggleButton android:id="@+id/toggle1"
+
+        <ToggleButton
+            android:id="@+id/toggle1"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content" />
-   
-        <ToggleButton android:id="@+id/toggle2"
+
+        <ToggleButton
+            android:id="@+id/toggle2"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content" />
-             
-        <Spinner android:id="@+id/spinner1"
+
+        <Spinner
+            android:id="@+id/spinner1"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:drawSelectorOnTop="true"
-        />
+            android:drawSelectorOnTop="true" />
 
         <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="5dip"
-            android:text="@string/textColorPrimary"
-            android:textAppearance="?android:attr/textAppearanceLarge"
             android:focusable="true"
-        />
+            android:text="@string/textColorPrimary"
+            android:textAppearance="?android:attr/textAppearanceLarge" />
 
         <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="5dip"
+            android:focusable="true"
             android:text="@string/textColorSecondary"
             android:textAppearance="?android:attr/textAppearanceLarge"
-            android:textColor="?android:attr/textColorSecondary"
-            android:focusable="true"
-        />
+            android:textColor="?android:attr/textColorSecondary" />
 
         <TextView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="5dip"
+            android:focusable="true"
             android:text="@string/textColorTertiary"
             android:textAppearance="?android:attr/textAppearanceLarge"
-            android:textColor="?android:attr/textColorTertiary"
-            android:focusable="true"
-        />
+            android:textColor="?android:attr/textColorTertiary" />
 
         <TextView
             style="?android:attr/listSeparatorTextViewStyle"
-            android:text="@string/listSeparatorTextViewStyle"
             android:layout_marginTop="5dip"
-        />
+            android:text="@string/listSeparatorTextViewStyle" />
 
         <TextView
-            android:layout_height="wrap_content"
             android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_marginTop="400dip"
-            android:textAppearance="?android:attr/textAppearanceLarge"
             android:text="(And all inside of a ScrollView!)"
-        />
-        
+            android:textAppearance="?android:attr/textAppearanceLarge" />
     </LinearLayout>
 
-</ScrollView>
+</ScrollView>
\ No newline at end of file
diff --git a/samples/ApiDemos/res/layout/image_block.xml b/samples/ApiDemos/res/layout/image_block.xml
new file mode 100644
index 0000000..58d6a23
--- /dev/null
+++ b/samples/ApiDemos/res/layout/image_block.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:clipChildren="true"
+            android:columnCount="2"
+            android:rowCount="4"
+        >
+    <ImageView android:id="@+id/ducky"
+               android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:scaleType="center"
+               android:layout_column="0"
+               android:layout_row="0"
+               android:src="@drawable/ducky"
+               android:onClick="clicked"
+               android:sharedElementName="ducky"
+            />
+    <ImageView android:id="@+id/woot"
+               android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:scaleType="center"
+               android:src="@drawable/woot"
+               android:layout_column="1"
+               android:layout_row="0"
+               android:onClick="clicked"
+               android:sharedElementName="woot"
+            />
+    <ImageView android:id="@+id/ball"
+               android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:scaleType="center"
+               android:src="@drawable/ball"
+               android:layout_column="0"
+               android:layout_row="1"
+               android:onClick="clicked"
+               android:sharedElementName="ball"
+            />
+    <ImageView android:id="@+id/block"
+               android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:scaleType="center"
+               android:src="@drawable/block"
+               android:layout_column="1"
+               android:layout_row="1"
+               android:onClick="clicked"
+               android:sharedElementName="block"
+            />
+    <ImageView android:id="@+id/jellies"
+               android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:scaleType="center"
+               android:src="@drawable/jellies"
+               android:layout_column="0"
+               android:layout_row="2"
+               android:onClick="clicked"
+               android:sharedElementName="jellies"
+            />
+    <ImageView android:id="@+id/mug"
+               android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:scaleType="center"
+               android:src="@drawable/mug"
+               android:layout_column="1"
+               android:layout_row="2"
+               android:onClick="clicked"
+               android:sharedElementName="mug"
+            />
+    <ImageView android:id="@+id/pencil"
+               android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:scaleType="center"
+               android:src="@drawable/pencil"
+               android:layout_column="0"
+               android:layout_row="3"
+               android:onClick="clicked"
+               android:sharedElementName="pencil"
+            />
+    <ImageView android:id="@+id/scissors"
+               android:layout_height="wrap_content"
+               android:layout_width="wrap_content"
+               android:scaleType="center"
+               android:src="@drawable/scissors"
+               android:layout_column="1"
+               android:layout_row="3"
+               android:onClick="clicked"
+               android:sharedElementName="scissors"
+            />
+</GridLayout>
\ No newline at end of file
diff --git a/samples/ApiDemos/res/layout/image_details.xml b/samples/ApiDemos/res/layout/image_details.xml
new file mode 100644
index 0000000..c58d704
--- /dev/null
+++ b/samples/ApiDemos/res/layout/image_details.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+             android:layout_width="match_parent"
+             android:layout_height="match_parent"
+             android:orientation="vertical"
+             android:clipChildren="false"
+        >
+    <FrameLayout android:id="@+id/shared_element"
+                   android:layout_height="0px"
+                   android:layout_weight="1"
+                   android:layout_width="match_parent"
+                   android:sharedElementName="hero"
+                   android:onClick="clicked"
+                   android:clipChildren="false">
+        <ImageView android:id="@+id/titleImage"
+                   android:layout_height="wrap_content"
+                   android:layout_width="wrap_content"
+                   android:scaleType="center"
+                   android:layout_gravity="left|bottom"
+                />
+    </FrameLayout>
+    <LinearLayout android:layout_height="0px"
+                  android:layout_width="match_parent"
+                  android:layout_weight="2"
+                  android:orientation="vertical"
+            >
+        <View android:layout_width="match_parent"
+              android:layout_height="2dp"
+              android:background="#808080"/>
+        <TextView android:layout_height="wrap_content"
+                  android:layout_width="match_parent"
+                  android:text="Ducky"
+                  android:textSize="30sp"
+                />
+        <View android:layout_width="match_parent"
+              android:layout_height="2dp"
+              android:background="#808080"/>
+        <TextView android:layout_height="wrap_content"
+                  android:layout_width="match_parent"
+                  android:text="Woot!"
+                  android:textSize="30sp"
+                />
+        <View android:layout_width="match_parent"
+              android:layout_height="2dp"
+              android:background="#808080"/>
+        <TextView android:layout_height="wrap_content"
+                  android:layout_width="match_parent"
+                  android:text="Ball"
+                  android:textSize="30sp"
+                />
+        <View android:layout_width="match_parent"
+              android:layout_height="2dp"
+              android:background="#808080"/>
+        <TextView android:layout_height="wrap_content"
+                  android:layout_width="match_parent"
+                  android:text="Block"
+                  android:textSize="30sp"
+                />
+        <View android:layout_width="match_parent"
+              android:layout_height="2dp"
+              android:background="#808080"/>
+        <TextView android:layout_height="wrap_content"
+                  android:layout_width="match_parent"
+                  android:text="Jelly Bean"
+                  android:textSize="30sp"
+                />
+        <View android:layout_width="match_parent"
+              android:layout_height="2dp"
+              android:background="#808080"/>
+        <TextView android:layout_height="wrap_content"
+                  android:layout_width="match_parent"
+                  android:text="Mug"
+                  android:textSize="30sp"
+                />
+        <View android:layout_width="match_parent"
+              android:layout_height="2dp"
+              android:background="#808080"/>
+        <TextView android:layout_height="wrap_content"
+                  android:layout_width="match_parent"
+                  android:text="Pencil"
+                  android:textSize="30sp"
+                />
+        <View android:layout_width="match_parent"
+              android:layout_height="2dp"
+              android:background="#808080"/>
+        <TextView android:layout_height="wrap_content"
+                  android:layout_width="match_parent"
+                  android:text="Scissors"
+                  android:textSize="30sp"
+                />
+
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/ApiDemos/res/layout/path_animations.xml b/samples/ApiDemos/res/layout/path_animations.xml
new file mode 100644
index 0000000..93abc98
--- /dev/null
+++ b/samples/ApiDemos/res/layout/path_animations.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="match_parent"
+              android:layout_height="match_parent">
+    <ScrollView android:layout_width="match_parent"
+                android:layout_height="wrap_content">
+        <RadioGroup android:orientation="horizontal"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:id="@+id/path_animation_type"
+                >
+            <RadioButton android:id="@+id/named_components"
+                         android:layout_width="wrap_content"
+                         android:layout_height="wrap_content"
+                         android:text="Named Components"/>
+            <RadioButton android:id="@+id/property_components"
+                         android:layout_width="wrap_content"
+                         android:layout_height="wrap_content"
+                         android:text="Property Components"/>
+            <RadioButton android:id="@+id/multi_int"
+                         android:layout_width="wrap_content"
+                         android:layout_height="wrap_content"
+                         android:text="Multi-int"/>
+            <RadioButton android:id="@+id/multi_float"
+                         android:layout_width="wrap_content"
+                         android:layout_height="wrap_content"
+                         android:text="Multi-float"/>
+            <RadioButton android:id="@+id/named_setter"
+                         android:layout_width="wrap_content"
+                         android:layout_height="wrap_content"
+                         android:text="Named Property"/>
+            <RadioButton android:id="@+id/property_setter"
+                         android:layout_width="wrap_content"
+                         android:layout_height="wrap_content"
+                         android:text="Property"/>
+        </RadioGroup>
+    </ScrollView>
+    <view class="com.example.android.apis.animation.PathAnimations$CanvasView"
+          android:id="@+id/canvas"
+          android:layout_width="match_parent"
+          android:layout_height="0px"
+          android:layout_weight="1">
+        <ImageView android:id="@+id/moved_item"
+                   android:layout_width="wrap_content"
+                   android:layout_height="wrap_content"
+                   android:src="@drawable/frog"/>
+    </view>
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/ApiDemos/res/layout/transition_scene1.xml b/samples/ApiDemos/res/layout/transition_scene1.xml
index a98da60..19fbe89 100644
--- a/samples/ApiDemos/res/layout/transition_scene1.xml
+++ b/samples/ApiDemos/res/layout/transition_scene1.xml
@@ -18,36 +18,40 @@
               android:layout_height="match_parent"
               android:id="@+id/container">
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="50dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_alignParentTop="true"
             android:layout_alignParentLeft="true"
             android:background="#f00"
+            android:text="Hello"
             android:id="@+id/view1"/>
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="50dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_alignParentTop="true"
             android:layout_alignParentRight="true"
             android:background="#0f0"
+            android:text="World"
             android:id="@+id/view2"/>
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="50dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:background="#00f"
             android:layout_alignParentBottom="true"
             android:layout_alignParentLeft="true"
+            android:text="Foo"
             android:id="@+id/view3"/>
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="50dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:background="#0ff"
             android:layout_alignParentBottom="true"
             android:layout_alignParentRight="true"
+            android:text="Bar"
             android:id="@+id/view4"/>
 
 </RelativeLayout>
diff --git a/samples/ApiDemos/res/layout/transition_scene2.xml b/samples/ApiDemos/res/layout/transition_scene2.xml
index fda2276..2d7e546 100644
--- a/samples/ApiDemos/res/layout/transition_scene2.xml
+++ b/samples/ApiDemos/res/layout/transition_scene2.xml
@@ -18,36 +18,40 @@
                 android:layout_height="match_parent"
                 android:id="@+id/container">
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="100dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_alignParentTop="true"
             android:layout_alignParentRight="true"
             android:background="#f00"
+            android:text="Hello"
             android:id="@+id/view1"/>
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="100dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_alignParentBottom="true"
             android:layout_alignParentLeft="true"
             android:background="#0f0"
+            android:text="World"
             android:id="@+id/view2"/>
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="100dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:background="#00f"
             android:layout_alignParentBottom="true"
             android:layout_alignParentRight="true"
+            android:text="Foo"
             android:id="@+id/view3"/>
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="100dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:background="#0ff"
             android:layout_alignParentTop="true"
             android:layout_alignParentLeft="true"
+            android:text="Bar"
             android:id="@+id/view4"/>
 
 </RelativeLayout>
diff --git a/samples/ApiDemos/res/layout/transition_scene3.xml b/samples/ApiDemos/res/layout/transition_scene3.xml
index 39c4da7..43ffc38 100644
--- a/samples/ApiDemos/res/layout/transition_scene3.xml
+++ b/samples/ApiDemos/res/layout/transition_scene3.xml
@@ -18,36 +18,40 @@
                 android:layout_height="match_parent"
                 android:id="@+id/container">
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="50dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_alignParentTop="true"
             android:layout_alignParentLeft="true"
             android:background="#f00"
+            android:text="Hello"
             android:id="@+id/view1"/>
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="50dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:layout_alignParentTop="true"
             android:layout_alignParentRight="true"
             android:background="#0f0"
+            android:text="World"
             android:id="@+id/view2"/>
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="50dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:background="#00f"
             android:layout_alignParentBottom="true"
             android:layout_alignParentLeft="true"
+            android:text="Foo"
             android:id="@+id/view3"/>
 
-    <View
-            android:layout_width="100dip"
-            android:layout_height="50dip"
+    <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
             android:background="#0ff"
             android:layout_alignParentBottom="true"
             android:layout_alignParentRight="true"
+            android:text="Bar"
             android:id="@+id/view4"/>
 
     <LinearLayout
diff --git a/samples/ApiDemos/res/transition/activity_transition_mgr.xml b/samples/ApiDemos/res/transition/activity_transition_mgr.xml
new file mode 100644
index 0000000..f1f461b
--- /dev/null
+++ b/samples/ApiDemos/res/transition/activity_transition_mgr.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+<transitionManager xmlns:android="http://schemas.android.com/apk/res/android">
+</transitionManager>
diff --git a/samples/ApiDemos/res/values-v11/styles.xml b/samples/ApiDemos/res/values-v11/styles.xml
index 3b4fead..46ed272 100644
--- a/samples/ApiDemos/res/values-v11/styles.xml
+++ b/samples/ApiDemos/res/values-v11/styles.xml
@@ -16,11 +16,11 @@
 
 <resources>
     <!-- For API level 11 or later, the Holo theme is available and we prefer that. -->
-    <style name="ThemeHolo" parent="android:Theme.Holo">
+    <style name="ThemeCurrent" parent="android:Theme.Holo">
     </style>
 
     <!-- For API level 11 or later, the Holo theme is available and we prefer that. -->
-    <style name="ThemeHoloDialog" parent="android:Theme.Holo.Dialog">
+    <style name="ThemeCurrentDialog" parent="android:Theme.Holo.Dialog">
     </style>
 
     <!-- For API level 11 or later, we can use the magical DialogWhenLarge theme. -->
diff --git a/samples/ApiDemos/res/values-v19/bools.xml b/samples/ApiDemos/res/values-v19/bools.xml
index 136d8fe..3a4b91e 100644
--- a/samples/ApiDemos/res/values-v19/bools.xml
+++ b/samples/ApiDemos/res/values-v19/bools.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!-- Copyright (C) 2014 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.
@@ -15,8 +15,8 @@
 -->
 
 <resources>
-    <!-- This resource is true if running under at least KitKat
+    <!-- This resource is true if running under at least L-Release
          API level.  The default value is false; an alternative value
-         for KitKat is true. -->
-    <bool name="atLeastKitKat">true</bool>
+         for L-Release is true. -->
+    <bool name="atLeastLRelease">true</bool>
 </resources>
diff --git a/samples/ApiDemos/res/values-v19/styles.xml b/samples/ApiDemos/res/values-v19/styles.xml
new file mode 100644
index 0000000..8307228
--- /dev/null
+++ b/samples/ApiDemos/res/values-v19/styles.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2014 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.
+-->
+
+<resources>
+    <!-- For API level XX or later, the Quantum theme is available and we prefer that. -->
+    <style name="ThemeCurrent" parent="android:Theme.Quantum.Light">
+    </style>
+
+    <!-- For API level XX or later, the Holo theme is available and we prefer that. -->
+    <style name="ThemeCurrentDialog" parent="android:Theme.Quantum.Light.Dialog">
+    </style>
+
+    <!-- For API level XX or later, we can use the magical DialogWhenLarge theme. -->
+    <style name="ThemeCurrentDialogWhenLarge" parent="android:style/Theme.Quantum.Light.DialogWhenLarge">
+    </style>
+
+    <style name="ActivityTransitionTheme" parent="android:style/Theme.Quantum.Light">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentTransitionManager">@transition/activity_transition_mgr</item>
+    </style>
+</resources>
diff --git a/samples/ApiDemos/res/values-v99/bools.xml b/samples/ApiDemos/res/values-v99/bools.xml
new file mode 100644
index 0000000..136d8fe
--- /dev/null
+++ b/samples/ApiDemos/res/values-v99/bools.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 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.
+-->
+
+<resources>
+    <!-- This resource is true if running under at least KitKat
+         API level.  The default value is false; an alternative value
+         for KitKat is true. -->
+    <bool name="atLeastKitKat">true</bool>
+</resources>
diff --git a/samples/ApiDemos/res/values-v99/styles.xml b/samples/ApiDemos/res/values-v99/styles.xml
new file mode 100644
index 0000000..33a7472
--- /dev/null
+++ b/samples/ApiDemos/res/values-v99/styles.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.
+-->
+
+<resources>
+    <!-- For API level XX or later, the Quantum theme is available and we prefer that. -->
+    <style name="ThemeCurrent" parent="android:Theme.Quantum">
+    </style>
+
+    <!-- For API level XX or later, the Holo theme is available and we prefer that. -->
+    <style name="ThemeCurrentDialog" parent="android:Theme.Quantum.Dialog">
+    </style>
+
+    <!-- For API level XX or later, we can use the magical DialogWhenLarge theme. -->
+    <style name="ThemeCurrentDialogWhenLarge" parent="android:style/Theme.Quantum.DialogWhenLarge">
+    </style>
+
+    <style name="ActivityTransitionTheme" parent="android:style/Theme.Quantum">
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentTransitionManager">@transition/activity_transition_mgr</item>
+    </style>
+</resources>
diff --git a/samples/ApiDemos/res/values/bools.xml b/samples/ApiDemos/res/values/bools.xml
index fa3f25f..127c142 100644
--- a/samples/ApiDemos/res/values/bools.xml
+++ b/samples/ApiDemos/res/values/bools.xml
@@ -49,4 +49,9 @@
          for KitKat is true. -->
     <bool name="atLeastKitKat">false</bool>
 
+    <!-- This resource is true if running under at least L-Release
+         API level.  The default value is false; an alternative value
+         for L-Release is true. -->
+    <bool name="atLeastLRelease">false</bool>
+
 </resources>
diff --git a/samples/ApiDemos/res/values/colors.xml b/samples/ApiDemos/res/values/colors.xml
index f2534d1..fd68af3 100644
--- a/samples/ApiDemos/res/values/colors.xml
+++ b/samples/ApiDemos/res/values/colors.xml
@@ -28,5 +28,6 @@
     <color name="solid_blue">#0000ff</color>
     <color name="solid_green">#f0f0</color>
     <color name="solid_yellow">#ffffff00</color>
+    <color name="purply">#ff884488</color>
 
 </resources>
diff --git a/samples/ApiDemos/res/values/styles.xml b/samples/ApiDemos/res/values/styles.xml
index 49a1c25..7ef0e28 100644
--- a/samples/ApiDemos/res/values/styles.xml
+++ b/samples/ApiDemos/res/values/styles.xml
@@ -26,25 +26,33 @@
     <!-- This is a theme that will adjust itself depending on the API version.
          The default definition is the safe one, using a theme that has always
          been defined.  Look at values-11/styles.xml for a variation that is
-         selected when the holographic theme is available. -->
-    <style name="ThemeHolo" parent="android:Theme">
+         selected when the holographic theme is available, or look at
+         values-XX/styles.xml for a variation that is selected when the quantum
+         theme is available. -->
+    <style name="ThemeCurrent" parent="android:Theme">
     </style>
 
     <!-- This is a theme that will adjust itself depending on the API version.
          The default definition is the safe one, using a theme that has always
          been defined.  Look at values-11/styles.xml for a variation that is
-         selected when the holographic theme is available. -->
-    <style name="ThemeHoloDialog" parent="android:Theme.Dialog">
+         selected when the holographic theme is available, or look at
+         values-XX/styles.xml for a variation that is selected when the quantum
+         theme is available. -->
+    <style name="ThemeCurrentDialog" parent="android:Theme.Dialog">
+    </style>
+
+    <!-- Older platforms don't have Theme.Holo.DialogWhenLarge; we will define
+         our own wrapper theme that uses it only when running on the appropriate
+         platform version.  On older platforms, we always use the generic
+         fullscreen theme, because they don't support some feature that help
+         in correctly laying out an activity as a dialog. -->
+    <style name="ThemeCurrentDialogWhenLarge" parent="android:style/Theme">
     </style>
 
     <!-- Base application theme is the default theme. -->
     <style name="Theme" parent="android:Theme">
     </style>
 
-    <!-- Base application theme is the default theme. -->
-    <style name="BadTheme" parent="@android:style/Theme.Holo.Light.NoActionBar">
-    </style>
-
     <!-- Variation on our application theme that forces a plain
         text style. -->
     <style name="Theme.PlainText">
@@ -91,14 +99,6 @@
         <item name="android:windowNoTitle">true</item>
         <item name="android:colorForeground">#fff</item>
     </style>
-    
-    <!-- Older platforms don't have Theme.Holo.DialogWhenLarge; we will define
-         our own wrapper theme that uses it only when running on the appropriate
-         platform version.  On older platforms, we always use the generic
-         fullscreen theme, because they don't support some feature that help
-         in correctly laying out an activity as a dialog. -->
-    <style name="ThemeDialogWhenLarge" parent="android:style/Theme">
-    </style>
 
     <style name="TextAppearance.Theme.PlainText" parent="android:TextAppearance.Theme">
         <item name="android:textStyle">normal</item>
@@ -121,4 +121,11 @@
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
     </style>
+
+    <style name="ActivityTransitionTheme" parent="android:style/Theme.Holo">
+        <item name="android:windowIsTranslucent">true</item>
+	      <item name="android:windowBackground">@android:color/transparent</item>
+        <item name="android:windowContentTransitionManager">@transition/activity_transition_mgr</item>
+    </style>
+
 </resources>
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/ActivityTransition.java b/samples/ApiDemos/src/com/example/android/apis/animation/ActivityTransition.java
new file mode 100644
index 0000000..2c8c042
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/ActivityTransition.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2013 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.animation;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.content.Intent;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+import android.transition.TransitionSet;
+import android.util.ArrayMap;
+import android.util.Pair;
+import android.view.View;
+import android.view.Window;
+import android.widget.ImageView;
+
+import java.util.Random;
+
+/**
+ *
+ */
+public class ActivityTransition extends Activity {
+
+    private static final String TAG = "ActivityTransition";
+
+    private static final String KEY_ID = "ViewTransitionValues:id";
+
+    private Random mRandom = new Random();
+
+    private ImageView mHero;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_CONTENT_TRANSITIONS);
+        getWindow().setTriggerEarlyEnterTransition(true);
+        getWindow().setBackgroundDrawable(new ColorDrawable(randomColor()));
+        setContentView(R.layout.image_block);
+        setupHero();
+        TransitionManager transitionManager = getContentTransitionManager();
+        TransitionSet transitions = new TransitionSet();
+        Fall fall = new Fall();
+        fall.setDuration(600);
+        transitions.addTransition(fall);
+        transitions.addTransition(new ScaleTransition());
+        transitions.addTransition(new ChangeBounds());
+        transitions.addTransition(new Up());
+        transitionManager.setTransition(getContentScene(), transitions);
+        transitionManager.setExitTransition(getContentScene(), transitions);
+    }
+
+    private void setupHero() {
+        int id = getIntent().getIntExtra(KEY_ID, 0);
+        mHero = (ImageView) findViewById(id);
+        if (mHero != null) {
+            ArrayMap<String, String> sharedElementsMap = new ArrayMap<String, String>();
+            sharedElementsMap.put("hero", mHero.getSharedElementName());
+            getWindow().mapTransitionTargets(sharedElementsMap);
+        }
+    }
+
+    public void clicked(View v) {
+        mHero = (ImageView) v;
+        Intent intent = new Intent(this, ActivityTransitionDetails.class);
+        intent.putExtra(KEY_ID, v.getId());
+        ActivityOptions activityOptions
+                = ActivityOptions.makeSceneTransitionAnimation(mHero, "hero");
+        startActivity(intent, activityOptions.toBundle());
+    }
+
+    private int randomColor() {
+        int red = mRandom.nextInt(128);
+        int green = mRandom.nextInt(128);
+        int blue = mRandom.nextInt(128);
+        return 0xFF000000 | (red << 16) | (green << 8) | blue;
+    }
+
+    @Override
+    public void onCaptureSharedElementStart(Transition transition) {
+        int width = mHero.getWidth();
+        int newTop = mHero.getBottom() - width;
+        mHero.setTop(newTop);
+
+        int imageWidth = mHero.getDrawable().getIntrinsicWidth();
+        mHero.setPivotX(0);
+        mHero.setPivotY(0);
+        float scale = ((float)width)/imageWidth;
+        mHero.setScaleX(scale);
+        mHero.setScaleY(scale);
+    }
+
+    @Override
+    public void onCaptureSharedElementEnd() {
+        mHero.setPivotX(0);
+        mHero.setPivotY(0);
+        mHero.setScaleX(1);
+        mHero.setScaleY(1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/ActivityTransitionDetails.java b/samples/ApiDemos/src/com/example/android/apis/animation/ActivityTransitionDetails.java
new file mode 100644
index 0000000..2e40d9e
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/ActivityTransitionDetails.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2014 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.animation;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.content.Intent;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.transition.ChangeBounds;
+import android.transition.Transition;
+import android.transition.TransitionManager;
+import android.transition.TransitionSet;
+import android.util.Pair;
+import android.view.View;
+import android.view.Window;
+import android.widget.ImageView;
+
+import java.util.Random;
+
+/**
+ *
+ */
+public class ActivityTransitionDetails extends Activity {
+
+    private static final String TAG = "ActivityTransitionDetails";
+
+    private static final String KEY_ID = "ViewTransitionValues:id";
+
+    private Random mRandom = new Random();
+
+    private int mImageResourceId = R.drawable.ducky;
+
+    private int mId = R.id.ducky;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_CONTENT_TRANSITIONS);
+        getWindow().setTriggerEarlyEnterTransition(false);
+        getWindow().setBackgroundDrawable(new ColorDrawable(randomColor()));
+        setContentView(R.layout.image_details);
+        ImageView titleImage = (ImageView) findViewById(R.id.titleImage);
+        titleImage.setImageDrawable(getHeroDrawable());
+
+        TransitionManager transitionManager = getContentTransitionManager();
+        TransitionSet transitions = new TransitionSet();
+
+        Fall fall = new Fall();
+        fall.setDuration(600);
+        transitions.addTransition(fall);
+        transitions.addTransition(new Up());
+        transitions.addTransition(new ChangeBounds());
+        transitions.addTransition(new ScaleTransition());
+        transitionManager.setTransition(getContentScene(), transitions);
+        transitionManager.setExitTransition(getContentScene(), transitions);
+    }
+
+    @Override
+    public void onCaptureSharedElementStart(Transition transition) {
+        ImageView imageView = (ImageView) findViewById(R.id.titleImage);
+        imageView.setScaleX(1);
+        imageView.setScaleY(1);
+        imageView.offsetTopAndBottom(-imageView.getTop());
+    }
+
+    @Override
+    public void onCaptureSharedElementEnd() {
+        setScale();
+    }
+
+    private void setScale() {
+        ImageView imageView = (ImageView) findViewById(R.id.titleImage);
+        Drawable drawable = imageView.getDrawable();
+        float intrinsicWidth = drawable.getIntrinsicWidth();
+        View sharedElementTarget = findViewById(R.id.shared_element);
+        float scale = sharedElementTarget.getWidth()/intrinsicWidth;
+        imageView.setPivotY(imageView.getHeight());
+        imageView.setScaleX(scale);
+        imageView.setScaleY(scale);
+    }
+
+    private Drawable getHeroDrawable() {
+        int id = getIntent().getIntExtra(KEY_ID, mId);
+        mId = id;
+
+        int resourceId;
+        switch (id) {
+            case R.id.ducky:
+                resourceId = R.drawable.ducky;
+                break;
+            case R.id.jellies:
+                resourceId = R.drawable.jellies;
+                break;
+            case R.id.mug:
+                resourceId = R.drawable.mug;
+                break;
+            case R.id.pencil:
+                resourceId = R.drawable.pencil;
+                break;
+            case R.id.scissors:
+                resourceId = R.drawable.scissors;
+                break;
+            case R.id.woot:
+                resourceId = R.drawable.woot;
+                break;
+            case R.id.ball:
+                resourceId = R.drawable.ball;
+                break;
+            case R.id.block:
+                resourceId = R.drawable.block;
+                break;
+            default:
+                resourceId = mImageResourceId;
+                break;
+        }
+        mImageResourceId = resourceId;
+        return getResources().getDrawable(resourceId);
+    }
+
+    public void clicked(View v) {
+        Intent intent = new Intent(this, ActivityTransition.class);
+        intent.putExtra(KEY_ID, mId);
+        ActivityOptions activityOptions = ActivityOptions.makeSceneTransitionAnimation(v, "hero");
+        startActivity(intent, activityOptions.toBundle());
+    }
+
+    private int randomColor() {
+        int red = mRandom.nextInt(128);
+        int green = mRandom.nextInt(128);
+        int blue = mRandom.nextInt(128);
+        return 0xFF000000 | (red << 16) | (green << 8) | blue;
+    }
+
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/Fall.java b/samples/ApiDemos/src/com/example/android/apis/animation/Fall.java
new file mode 100644
index 0000000..6a866e5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/Fall.java
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2014 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.animation;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.transition.Transition;
+import android.transition.TransitionValues;
+import android.transition.Visibility;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.DecelerateInterpolator;
+
+/**
+ *
+ */
+public class Fall extends Visibility {
+    private static final TimeInterpolator sDecelerate = new DecelerateInterpolator();
+    private static final TimeInterpolator sAccelerate = new AccelerateInterpolator();
+    private static final String TAG = "Fall";
+    private static final String PROPNAME_SCREEN_LOCATION = "android:fade:screen_location";
+
+    private View mFocusElement;
+
+    private Animator createAnimation(final View view, long startDelay, final float startY,
+            float endY, AnimatorListenerAdapter listener, TimeInterpolator interpolator) {
+        if (startY == endY) {
+            // run listener if we're noop'ing the animation, to get the end-state results now
+            if (listener != null) {
+                listener.onAnimationEnd(null);
+            }
+            return null;
+        }
+        final ObjectAnimator anim = ObjectAnimator.ofFloat(view, View.TRANSLATION_Y, startY, endY);
+
+        if (listener != null) {
+            anim.addListener(listener);
+            anim.addPauseListener(listener);
+        }
+        anim.setInterpolator(interpolator);
+        anim.setStartDelay(startDelay);
+        AnimatorSet wrapper = new AnimatorSet();
+        wrapper.play(anim);
+        wrapper.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                view.setTranslationY(startY);
+            }
+        });
+        return wrapper;
+    }
+
+    private void captureValues(TransitionValues transitionValues) {
+        int[] loc = new int[2];
+        transitionValues.view.getLocationOnScreen(loc);
+        transitionValues.values.put(PROPNAME_SCREEN_LOCATION, loc);
+    }
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        super.captureStartValues(transitionValues);
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        super.captureEndValues(transitionValues);
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public Animator onAppear(ViewGroup sceneRoot,
+            TransitionValues startValues, int startVisibility,
+            TransitionValues endValues, int endVisibility) {
+        if (endValues == null) {
+            return null;
+        }
+        final View endView = endValues.view;
+        final float endY = endView.getTranslationY();
+        final float startY = endY + sceneRoot.getHeight();
+
+        TransitionListener transitionListener = new TransitionListener() {
+            boolean mCanceled = false;
+            float mPausedY;
+
+            @Override
+            public void onTransitionCancel(Transition transition) {
+                endView.setTranslationY(endY);
+                mCanceled = true;
+            }
+
+            @Override
+            public void onTransitionStart(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                if (!mCanceled) {
+                    endView.setTranslationY(endY);
+                }
+            }
+
+            @Override
+            public void onTransitionPause(Transition transition) {
+                mPausedY = endView.getTranslationY();
+                endView.setTranslationY(endY);
+            }
+
+            @Override
+            public void onTransitionResume(Transition transition) {
+                endView.setTranslationY(mPausedY);
+            }
+        };
+        addListener(transitionListener);
+        View sharedElement = getFocusElement(sceneRoot);
+        int[] loc = (int[]) endValues.values.get(PROPNAME_SCREEN_LOCATION);
+        long startDelay = calculateRiseStartDelay(sceneRoot, sharedElement, endView, loc);
+        return createAnimation(endView, startDelay, startY, endY, null, sDecelerate);
+    }
+
+    @Override
+    public Animator onDisappear(ViewGroup sceneRoot,
+            TransitionValues startValues, int startVisibility,
+            TransitionValues endValues, int endVisibility) {
+        View view = null;
+        View startView = (startValues != null) ? startValues.view : null;
+        View endView = (endValues != null) ? endValues.view : null;
+        View overlayView = null;
+        View viewToKeep = null;
+        if (endView == null || endView.getParent() == null) {
+            if (endView != null) {
+                // endView was removed from its parent - add it to the overlay
+                view = overlayView = endView;
+            } else if (startView != null) {
+                // endView does not exist. Use startView only under certain
+                // conditions, because placing a view in an overlay necessitates
+                // it being removed from its current parent
+                if (startView.getParent() == null) {
+                    // no parent - safe to use
+                    view = overlayView = startView;
+                } else if (startView.getParent() instanceof View &&
+                        startView.getParent().getParent() == null) {
+                    View startParent = (View) startView.getParent();
+                    int id = startParent.getId();
+                    if (id != View.NO_ID && sceneRoot.findViewById(id) != null && canRemoveViews()) {
+                        // no parent, but its parent is unparented  but the parent
+                        // hierarchy has been replaced by a new hierarchy with the same id
+                        // and it is safe to un-parent startView
+                        view = overlayView = startView;
+                    }
+                }
+            }
+        } else {
+            // visibility change
+            if (endVisibility == View.INVISIBLE) {
+                view = endView;
+                viewToKeep = view;
+            } else {
+                // Becoming GONE
+                if (startView == endView) {
+                    view = endView;
+                    viewToKeep = view;
+                } else {
+                    view = startView;
+                    overlayView = view;
+                }
+            }
+        }
+        final int finalVisibility = endVisibility;
+        View sharedElement = getFocusElement(sceneRoot);
+
+        int[] loc = (int[]) startValues.values.get(PROPNAME_SCREEN_LOCATION);
+        // TODO: add automatic facility to Visibility superclass for keeping views around
+        if (overlayView != null) {
+            // TODO: Need to do this for general case of adding to overlay
+            long startDelay = calculateFallStartDelay(sceneRoot, sharedElement, overlayView, loc);
+            int screenX = loc[0];
+            int screenY = loc[1];
+            loc = new int[2];
+            sceneRoot.getLocationOnScreen(loc);
+            overlayView.offsetLeftAndRight((screenX - loc[0]) - overlayView.getLeft());
+            overlayView.offsetTopAndBottom((screenY - loc[1]) - overlayView.getTop());
+            sceneRoot.getOverlay().add(overlayView);
+            // TODO: add automatic facility to Visibility superclass for keeping views around
+            final float startY = overlayView.getTranslationY();
+            float endY = startY + sceneRoot.getHeight();
+            final View finalView = view;
+            final View finalOverlayView = overlayView;
+            final View finalViewToKeep = viewToKeep;
+            final ViewGroup finalSceneRoot = sceneRoot;
+            final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    finalView.setTranslationY(startY);
+                    // TODO: restore view offset from overlay repositioning
+                    if (finalViewToKeep != null) {
+                        finalViewToKeep.setVisibility(finalVisibility);
+                    }
+                    if (finalOverlayView != null) {
+                        finalSceneRoot.getOverlay().remove(finalOverlayView);
+                    }
+                }
+
+                @Override
+                public void onAnimationPause(Animator animation) {
+                    if (finalOverlayView != null) {
+                        finalSceneRoot.getOverlay().remove(finalOverlayView);
+                    }
+                }
+
+                @Override
+                public void onAnimationResume(Animator animation) {
+                    if (finalOverlayView != null) {
+                        finalSceneRoot.getOverlay().add(finalOverlayView);
+                    }
+                }
+            };
+            return createAnimation(view, startDelay, startY, endY, endListener, sAccelerate);
+        }
+        if (viewToKeep != null) {
+            long startDelay = calculateFallStartDelay(sceneRoot, sharedElement, viewToKeep, loc);
+            // TODO: find a different way to do this, like just changing the view to be
+            // VISIBLE for the duration of the transition
+            viewToKeep.setVisibility((View.VISIBLE));
+            // TODO: add automatic facility to Visibility superclass for keeping views around
+            final float startY = viewToKeep.getTranslationY();
+            float endY = startY + sceneRoot.getHeight();
+            final View finalView = view;
+            final View finalOverlayView = overlayView;
+            final View finalViewToKeep = viewToKeep;
+            final ViewGroup finalSceneRoot = sceneRoot;
+            final AnimatorListenerAdapter endListener = new AnimatorListenerAdapter() {
+                boolean mCanceled = false;
+                float mPausedY = -1;
+
+                @Override
+                public void onAnimationPause(Animator animation) {
+                    if (finalViewToKeep != null && !mCanceled) {
+                        finalViewToKeep.setVisibility(finalVisibility);
+                    }
+                    mPausedY = finalView.getTranslationY();
+                    finalView.setTranslationY(startY);
+                }
+
+                @Override
+                public void onAnimationResume(Animator animation) {
+                    if (finalViewToKeep != null && !mCanceled) {
+                        finalViewToKeep.setVisibility(View.VISIBLE);
+                    }
+                    finalView.setTranslationY(mPausedY);
+                }
+
+                @Override
+                public void onAnimationCancel(Animator animation) {
+                    mCanceled = true;
+                    if (mPausedY >= 0) {
+                        finalView.setTranslationY(mPausedY);
+                    }
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    if (!mCanceled) {
+                        finalView.setTranslationY(startY);
+                    }
+                    // TODO: restore view offset from overlay repositioning
+                    if (finalViewToKeep != null && !mCanceled) {
+                        finalViewToKeep.setVisibility(finalVisibility);
+                    }
+                    if (finalOverlayView != null) {
+                        finalSceneRoot.getOverlay().remove(finalOverlayView);
+                    }
+                }
+            };
+            return createAnimation(view, startDelay, startY, endY, endListener, sAccelerate);
+        }
+        return null;
+    }
+
+    private View getFocusElement(ViewGroup sceneRoot) {
+        if (mFocusElement == null) {
+            mFocusElement = findFocusElement(sceneRoot);
+            if (mFocusElement == null) {
+                mFocusElement = sceneRoot;
+            }
+        }
+        return (mFocusElement == sceneRoot) ? null : mFocusElement;
+    }
+
+    private static View findFocusElement(ViewGroup viewGroup) {
+        int numChildren = viewGroup.getChildCount();
+        for (int i = 0; i < numChildren; i++) {
+            View child = viewGroup.getChildAt(i);
+            String sharedElementName = child.getSharedElementName();
+            if (sharedElementName != null && !sharedElementName.startsWith("android:")) {
+                return child;
+            }
+            if (child instanceof ViewGroup) {
+                View sharedElement = findFocusElement((ViewGroup) child);
+                if (sharedElement != null) {
+                    return sharedElement;
+                }
+            }
+        }
+        return null;
+    }
+
+    private long calculateFallStartDelay(ViewGroup sceneRoot, View shared, View view,
+            int[] viewLoc) {
+        int[] loc = new int[2];
+        sceneRoot.getLocationOnScreen(loc);
+        int bottom = loc[1] + sceneRoot.getHeight();
+        float distance = bottom - viewLoc[1] + view.getTranslationY();
+        if (shared != null) {
+            shared.getLocationOnScreen(loc);
+            float heroX = loc[0] + shared.getTranslationX() + (shared.getWidth() / 2.0f);
+            float viewX = viewLoc[0] + view.getTranslationX() + (view.getWidth() / 2.0f);
+            float distanceX = Math.abs(heroX - viewX);
+            float distanceXRatio = distanceX / sceneRoot.getWidth();
+            distance += (1 - distanceXRatio) * shared.getHeight();
+        }
+        float distanceRatio = distance/sceneRoot.getHeight() / 3;
+        return Math.max(0, Math.round(distanceRatio * getDuration()));
+    }
+
+    private long calculateRiseStartDelay(View sceneRoot, View shared, View view, int[] viewLoc) {
+        int[] loc = new int[2];
+        sceneRoot.getLocationOnScreen(loc);
+        int top = loc[1];
+        float distance = viewLoc[1] + view.getTranslationY() - top;
+        if (shared != null) {
+            shared.getLocationOnScreen(loc);
+            float heroX = loc[0] + shared.getTranslationX() + (shared.getWidth() / 2.0f);
+            float viewX = viewLoc[0] + view.getTranslationX() + (view.getWidth() / 2.0f);
+            float distanceX = Math.abs(heroX - viewX);
+            float distanceXRatio = distanceX / sceneRoot.getWidth();
+            distance += distanceXRatio * shared.getHeight();
+        }
+        float distanceRatio = distance/sceneRoot.getHeight() / 3;
+        return Math.max(0, Math.round(distanceRatio * getDuration()));
+    }
+
+    @Override
+    public Transition clone() {
+        Fall transition = (Fall) super.clone();
+        transition.mFocusElement = null;
+        return transition;
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/PathAnimations.java b/samples/ApiDemos/src/com/example/android/apis/animation/PathAnimations.java
new file mode 100644
index 0000000..daa8d99
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/PathAnimations.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright (C) 2013 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.animation;
+
+import android.animation.ObjectAnimator;
+import android.animation.TypeConverter;
+import android.animation.ValueAnimator;
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.graphics.RectF;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.util.FloatMath;
+import android.util.Log;
+import android.util.Property;
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.LinearInterpolator;
+import android.widget.FrameLayout;
+import android.widget.RadioGroup;
+
+import com.example.android.apis.R;
+
+/** This application demonstrates the use of Path animation. */
+public class PathAnimations extends Activity implements
+        RadioGroup.OnCheckedChangeListener, View.OnLayoutChangeListener {
+
+    final static Path sTraversalPath = new Path();
+    final static float TRAVERSE_PATH_SIZE = 7.0f;
+
+    final static Property<PathAnimations, Point> POINT_PROPERTY
+            = new Property<PathAnimations, Point>(Point.class, "point") {
+        @Override
+        public Point get(PathAnimations object) {
+            View v = object.findViewById(R.id.moved_item);
+            return new Point(Math.round(v.getX()), Math.round(v.getY()));
+        }
+
+        @Override
+        public void set(PathAnimations object, Point value) {
+            object.setCoordinates(value.x, value.y);
+        }
+    };
+
+    static {
+        float inverse_sqrt8 = FloatMath.sqrt(0.125f);
+        RectF bounds = new RectF(1, 1, 3, 3);
+        sTraversalPath.addArc(bounds, 45, 180);
+        sTraversalPath.addArc(bounds, 225, 180);
+
+        bounds.set(1.5f + inverse_sqrt8, 1.5f + inverse_sqrt8, 2.5f + inverse_sqrt8,
+                2.5f + inverse_sqrt8);
+        sTraversalPath.addArc(bounds, 45, 180);
+        sTraversalPath.addArc(bounds, 225, 180);
+
+        bounds.set(4, 1, 6, 3);
+        sTraversalPath.addArc(bounds, 135, -180);
+        sTraversalPath.addArc(bounds, -45, -180);
+
+        bounds.set(4.5f - inverse_sqrt8, 1.5f + inverse_sqrt8, 5.5f - inverse_sqrt8, 2.5f + inverse_sqrt8);
+        sTraversalPath.addArc(bounds, 135, -180);
+        sTraversalPath.addArc(bounds, -45, -180);
+
+        sTraversalPath.addCircle(3.5f, 3.5f, 0.5f, Path.Direction.CCW);
+
+        sTraversalPath.addArc(new RectF(1, 2, 6, 6), 0, 180);
+    }
+
+    private CanvasView mCanvasView;
+
+    private ObjectAnimator mAnimator;
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.path_animations);
+        mCanvasView = (CanvasView) findViewById(R.id.canvas);
+        mCanvasView.addOnLayoutChangeListener(this);
+        ((RadioGroup) findViewById(R.id.path_animation_type)).setOnCheckedChangeListener(this);
+    }
+
+    public void setCoordinates(int x, int y) {
+        changeCoordinates((float) x, (float) y);
+    }
+
+    public void changeCoordinates(float x, float y) {
+        View v = findViewById(R.id.moved_item);
+        v.setX(x);
+        v.setY(y);
+    }
+
+    public void setPoint(PointF point) {
+        changeCoordinates(point.x, point.y);
+    }
+
+    @Override
+    public void onCheckedChanged(RadioGroup group, int checkedId) {
+        startAnimator(checkedId);
+    }
+
+    @Override
+    public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
+            int oldTop, int oldRight, int oldBottom) {
+        int checkedId = ((RadioGroup)findViewById(R.id.path_animation_type)).getCheckedRadioButtonId();
+        if (checkedId != RadioGroup.NO_ID) {
+            startAnimator(checkedId);
+        }
+    }
+
+    private void startAnimator(int checkedId) {
+        if (mAnimator != null) {
+            mAnimator.cancel();
+            mAnimator = null;
+        }
+
+        View view = findViewById(R.id.moved_item);
+        Path path = mCanvasView.getPath();
+        if (path.isEmpty()) {
+            return;
+        }
+
+        switch (checkedId) {
+            case R.id.named_components:
+                // Use the named "x" and "y" properties for individual (x, y)
+                // coordinates of the Path and set them on the view object.
+                // The setX(float) and setY(float) methods are called on view.
+                // An int version of this method also exists for animating
+                // int Properties.
+                mAnimator = ObjectAnimator.ofFloat(view, "x", "y", path);
+                break;
+            case R.id.property_components:
+                // Use two Properties for individual (x, y) coordinates of the Path
+                // and set them on the view object.
+                // An int version of this method also exists for animating
+                // int Properties.
+                mAnimator = ObjectAnimator.ofFloat(view, View.X, View.Y, path);
+                break;
+            case R.id.multi_int:
+                // Use a multi-int setter to animate along a Path. The method
+                // setCoordinates(int x, int y) is called on this during the animation.
+                // Either "setCoordinates" or "coordinates" are acceptable parameters
+                // because the "set" can be implied.
+                mAnimator = ObjectAnimator.ofMultiInt(this, "setCoordinates", path);
+                break;
+            case R.id.multi_float:
+                // Use a multi-float setter to animate along a Path. The method
+                // changeCoordinates(float x, float y) is called on this during the animation.
+                mAnimator = ObjectAnimator.ofMultiFloat(this, "changeCoordinates", path);
+                break;
+            case R.id.named_setter:
+                // Use the named "point" property to animate along the Path.
+                // There must be a method setPoint(PointF) on the animated object.
+                // Because setPoint takes a PointF parameter, no TypeConverter is necessary.
+                // In this case, the animated object is PathAnimations.
+                mAnimator = ObjectAnimator.ofObject(this, "point", null, path);
+                break;
+            case R.id.property_setter:
+                // Use the POINT_PROPERTY property to animate along the Path.
+                // POINT_PROPERTY takes a Point, not a PointF, so the TypeConverter
+                // PointFToPointConverter is necessary.
+                mAnimator = ObjectAnimator.ofObject(this, POINT_PROPERTY,
+                        new PointFToPointConverter(), path);
+                break;
+        }
+
+        mAnimator.setDuration(10000);
+        mAnimator.setRepeatMode(Animation.RESTART);
+        mAnimator.setRepeatCount(ValueAnimator.INFINITE);
+        mAnimator.setInterpolator(new LinearInterpolator());
+        mAnimator.start();
+    }
+
+    public static class CanvasView extends FrameLayout {
+
+        Path mPath = new Path();
+
+        Paint mPathPaint = new Paint();
+
+        public CanvasView(Context context) {
+            super(context);
+            init();
+        }
+
+        public CanvasView(Context context, AttributeSet attrs) {
+            super(context, attrs);
+            init();
+        }
+
+        public CanvasView(Context context, AttributeSet attrs, int defStyle) {
+            super(context, attrs, defStyle);
+            init();
+        }
+
+        private void init() {
+            setWillNotDraw(false);
+            mPathPaint.setColor(0xFFFF0000);
+            mPathPaint.setStrokeWidth(2.0f);
+            mPathPaint.setStyle(Paint.Style.STROKE);
+        }
+
+        @Override
+        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+            super.onLayout(changed, left, top, right, bottom);
+            if (changed) {
+                Matrix scale = new Matrix();
+                float scaleWidth = (right-left)/TRAVERSE_PATH_SIZE;
+                float scaleHeight= (bottom-top)/TRAVERSE_PATH_SIZE;
+                scale.setScale(scaleWidth, scaleHeight);
+                sTraversalPath.transform(scale, mPath);
+            }
+        }
+
+        public Path getPath() {
+            return mPath;
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+            canvas.drawPath(mPath, mPathPaint);
+            super.draw(canvas);
+        }
+    }
+
+    private static class PointFToPointConverter extends TypeConverter<PointF, Point> {
+        Point mPoint = new Point();
+
+        public PointFToPointConverter() {
+            super(PointF.class, Point.class);
+        }
+
+        @Override
+        public Point convert(PointF value) {
+            mPoint.set(Math.round(value.x), Math.round(value.y));
+            return mPoint;
+        }
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/ScaleTransition.java b/samples/ApiDemos/src/com/example/android/apis/animation/ScaleTransition.java
new file mode 100644
index 0000000..787cdb3
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/ScaleTransition.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 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.animation;
+
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.transition.Transition;
+import android.transition.TransitionValues;
+import android.util.Property;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ *
+ */
+public class ScaleTransition extends Transition {
+    private static final String PROPNAME_SCALE_X = "android:scale:x";
+    private static final String PROPNAME_SCALE_Y = "android:scale:y";
+    private static final String[] sTransitionProperties = {
+            PROPNAME_SCALE_X,
+            PROPNAME_SCALE_Y,
+    };
+
+    @Override
+    public String[] getTransitionProperties() {
+        return sTransitionProperties;
+    }
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    private void captureValues(TransitionValues transitionValues) {
+        transitionValues.values.put(PROPNAME_SCALE_X, transitionValues.view.getScaleX());
+        transitionValues.values.put(PROPNAME_SCALE_Y, transitionValues.view.getScaleY());
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        if (startValues == null || endValues == null) {
+            return null;
+        }
+        Animator scaleXAnimator = createScaleAnimator(startValues, endValues, PROPNAME_SCALE_X,
+                View.SCALE_X);
+        Animator scaleYAnimator = createScaleAnimator(startValues, endValues, PROPNAME_SCALE_Y,
+                View.SCALE_Y);
+        if (scaleXAnimator == null) {
+            return scaleYAnimator;
+        } else if (scaleYAnimator == null) {
+            return scaleXAnimator;
+        }
+        AnimatorSet animatorSet = new AnimatorSet();
+        animatorSet.playTogether(scaleXAnimator, scaleYAnimator);
+        return animatorSet;
+    }
+
+    private Animator createScaleAnimator(TransitionValues startValues, TransitionValues endValues,
+            String propertyName, Property<View, Float> scaleProperty) {
+        float start = (Float)startValues.values.get(propertyName);
+        float end = (Float)endValues.values.get(propertyName);
+        if (start == end) {
+            return null;
+        }
+        return ObjectAnimator.ofFloat(endValues.view, scaleProperty, start, end);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/Up.java b/samples/ApiDemos/src/com/example/android/apis/animation/Up.java
new file mode 100644
index 0000000..4d3bba5
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/Up.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2014 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.animation;
+
+import android.animation.Animator;
+import android.animation.ObjectAnimator;
+import android.transition.Transition;
+import android.transition.TransitionValues;
+import android.view.View;
+import android.view.ViewGroup;
+
+/**
+ *
+ */
+public class Up extends Transition {
+    private static final String PROPNAME_Z = "android:z:height";
+    private static final String[] sTransitionProperties = {
+            PROPNAME_Z,
+    };
+
+    @Override
+    public void captureStartValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    @Override
+    public void captureEndValues(TransitionValues transitionValues) {
+        captureValues(transitionValues);
+    }
+
+    private void captureValues(TransitionValues transitionValues) {
+        View view = transitionValues.view;
+        transitionValues.values.put(PROPNAME_Z, view.getTranslationZ());
+    }
+
+    @Override
+    public String[] getTransitionProperties() {
+        return sTransitionProperties;
+    }
+
+    @Override
+    public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
+            TransitionValues endValues) {
+        if (startValues == null || endValues == null) {
+            return null;
+        }
+        final float startZ = (Float)startValues.values.get(PROPNAME_Z);
+        final float endZ = (Float)endValues.values.get(PROPNAME_Z);
+        if (startZ == endZ) {
+            return null;
+        }
+        final View view = endValues.view;
+
+        TransitionListener transitionListener = new TransitionListener() {
+            boolean mCanceled = false;
+            float mPausedZ;
+
+            @Override
+            public void onTransitionCancel(Transition transition) {
+                view.setTranslationZ(endZ);
+                mCanceled = true;
+            }
+
+            @Override
+            public void onTransitionStart(Transition transition) {
+            }
+
+            @Override
+            public void onTransitionEnd(Transition transition) {
+                if (!mCanceled) {
+                    view.setTranslationZ(endZ);
+                }
+            }
+
+            @Override
+            public void onTransitionPause(Transition transition) {
+                mPausedZ = view.getTranslationZ();
+                view.setTranslationZ(endZ);
+            }
+
+            @Override
+            public void onTransitionResume(Transition transition) {
+                view.setTranslationZ(mPausedZ);
+            }
+        };
+        addListener(transitionListener);
+
+        return ObjectAnimator.ofFloat(view, View.TRANSLATION_Z, startZ, endZ);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/os/Sensors.java b/samples/ApiDemos/src/com/example/android/apis/os/Sensors.java
deleted file mode 100644
index 9863222..0000000
--- a/samples/ApiDemos/src/com/example/android/apis/os/Sensors.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * 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.
- */
-
-package com.example.android.apis.os;
-
-import android.app.Activity;
-import android.content.Context;
-import android.os.Bundle;
-import android.view.View;
-import android.hardware.Sensor;
-import android.hardware.SensorEvent;
-import android.hardware.SensorEventListener;
-import android.hardware.SensorManager;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.RectF;
-
-/**
- * <h3>Application that displays the values of the acceleration sensor graphically.</h3>
-
-<p>This demonstrates the {@link android.hardware.SensorManager android.hardware.SensorManager} class.
-
-<h4>Demo</h4>
-OS / Sensors
- 
-<h4>Source files</h4>
- * <table class="LinkTable">
- *         <tr>
- *             <td >src/com.example.android.apis/os/Sensors.java</td>
- *             <td >Sensors</td>
- *         </tr>
- * </table> 
- */
-public class Sensors extends Activity {
-    private SensorManager mSensorManager;
-    private GraphView mGraphView;
-
-    private class GraphView extends View implements SensorEventListener
-    {
-        private Bitmap  mBitmap;
-        private Paint   mPaint = new Paint();
-        private Canvas  mCanvas = new Canvas();
-        private Path    mPath = new Path();
-        private RectF   mRect = new RectF();
-        private float   mLastValues[] = new float[3*2];
-        private float   mOrientationValues[] = new float[3];
-        private int     mColors[] = new int[3*2];
-        private float   mLastX;
-        private float   mScale[] = new float[2];
-        private float   mYOffset;
-        private float   mMaxX;
-        private float   mSpeed = 1.0f;
-        private float   mWidth;
-        private float   mHeight;
-        
-        public GraphView(Context context) {
-            super(context);
-            mColors[0] = Color.argb(192, 255, 64, 64);
-            mColors[1] = Color.argb(192, 64, 128, 64);
-            mColors[2] = Color.argb(192, 64, 64, 255);
-            mColors[3] = Color.argb(192, 64, 255, 255);
-            mColors[4] = Color.argb(192, 128, 64, 128);
-            mColors[5] = Color.argb(192, 255, 255, 64);
-
-            mPaint.setFlags(Paint.ANTI_ALIAS_FLAG);
-            mRect.set(-0.5f, -0.5f, 0.5f, 0.5f);
-            mPath.arcTo(mRect, 0, 180);
-        }
-        
-        @Override
-        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
-            mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565);
-            mCanvas.setBitmap(mBitmap);
-            mCanvas.drawColor(0xFFFFFFFF);
-            mYOffset = h * 0.5f;
-            mScale[0] = - (h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));
-            mScale[1] = - (h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));
-            mWidth = w;
-            mHeight = h;
-            if (mWidth < mHeight) {
-                mMaxX = w;
-            } else {
-                mMaxX = w-50;
-            }
-            mLastX = mMaxX;
-            super.onSizeChanged(w, h, oldw, oldh);
-        }
-
-        @Override
-        protected void onDraw(Canvas canvas) {
-            synchronized (this) {
-                if (mBitmap != null) {
-                    final Paint paint = mPaint;
-                    final Path path = mPath;
-                    final int outer = 0xFFC0C0C0;
-                    final int inner = 0xFFff7010;
-
-                    if (mLastX >= mMaxX) {
-                        mLastX = 0;
-                        final Canvas cavas = mCanvas;
-                        final float yoffset = mYOffset;
-                        final float maxx = mMaxX;
-                        final float oneG = SensorManager.STANDARD_GRAVITY * mScale[0];
-                        paint.setColor(0xFFAAAAAA);
-                        cavas.drawColor(0xFFFFFFFF);
-                        cavas.drawLine(0, yoffset,      maxx, yoffset,      paint);
-                        cavas.drawLine(0, yoffset+oneG, maxx, yoffset+oneG, paint);
-                        cavas.drawLine(0, yoffset-oneG, maxx, yoffset-oneG, paint);
-                    }
-                    canvas.drawBitmap(mBitmap, 0, 0, null);
-
-                    float[] values = mOrientationValues;
-                    if (mWidth < mHeight) {
-                        float w0 = mWidth * 0.333333f;
-                        float w  = w0 - 32;
-                        float x = w0*0.5f;
-                        for (int i=0 ; i<3 ; i++) {
-                            canvas.save(Canvas.MATRIX_SAVE_FLAG);
-                            canvas.translate(x, w*0.5f + 4.0f);
-                            canvas.save(Canvas.MATRIX_SAVE_FLAG);
-                            paint.setColor(outer);
-                            canvas.scale(w, w);
-                            canvas.drawOval(mRect, paint);
-                            canvas.restore();
-                            canvas.scale(w-5, w-5);
-                            paint.setColor(inner);
-                            canvas.rotate(-values[i]);
-                            canvas.drawPath(path, paint);
-                            canvas.restore();
-                            x += w0;
-                        }
-                    } else {
-                        float h0 = mHeight * 0.333333f;
-                        float h  = h0 - 32;
-                        float y = h0*0.5f;
-                        for (int i=0 ; i<3 ; i++) {
-                            canvas.save(Canvas.MATRIX_SAVE_FLAG);
-                            canvas.translate(mWidth - (h*0.5f + 4.0f), y);
-                            canvas.save(Canvas.MATRIX_SAVE_FLAG);
-                            paint.setColor(outer);
-                            canvas.scale(h, h);
-                            canvas.drawOval(mRect, paint);
-                            canvas.restore();
-                            canvas.scale(h-5, h-5);
-                            paint.setColor(inner);
-                            canvas.rotate(-values[i]);
-                            canvas.drawPath(path, paint);
-                            canvas.restore();
-                            y += h0;
-                        }
-                    }
-
-                }
-            }
-        }
-
-        public void onSensorChanged(SensorEvent event) {
-            //Log.d(TAG, "sensor: " + sensor + ", x: " + values[0] + ", y: " + values[1] + ", z: " + values[2]);
-            synchronized (this) {
-                if (mBitmap != null) {
-                    final Canvas canvas = mCanvas;
-                    final Paint paint = mPaint;
-                    if (event.sensor.getType() == Sensor.TYPE_ORIENTATION) {
-                        for (int i=0 ; i<3 ; i++) {
-                            mOrientationValues[i] = event.values[i];
-                        }
-                    } else {
-                        float deltaX = mSpeed;
-                        float newX = mLastX + deltaX;
-
-                        int j = (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) ? 1 : 0;
-                        for (int i=0 ; i<3 ; i++) {
-                            int k = i+j*3;
-                            final float v = mYOffset + event.values[i] * mScale[j];
-                            paint.setColor(mColors[k]);
-                            canvas.drawLine(mLastX, mLastValues[k], newX, v, paint);
-                            mLastValues[k] = v;
-                        }
-                        if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
-                            mLastX += mSpeed;
-                    }
-                    invalidate();
-                }
-            }
-        }
-
-        public void onAccuracyChanged(Sensor sensor, int accuracy) {
-        }
-    }
-    
-    /**
-     * Initialization of the Activity after it is first created.  Must at least
-     * call {@link android.app.Activity#setContentView setContentView()} to
-     * describe what is to be displayed in the screen.
-     */
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        // Be sure to call the super class.
-        super.onCreate(savedInstanceState);
-
-        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
-        mGraphView = new GraphView(this);
-        setContentView(mGraphView);
-    }
-
-    @Override
-    protected void onResume() {
-        super.onResume();
-        mSensorManager.registerListener(mGraphView,
-                mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
-                SensorManager.SENSOR_DELAY_FASTEST);
-        mSensorManager.registerListener(mGraphView,
-                mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
-                SensorManager.SENSOR_DELAY_FASTEST);
-        mSensorManager.registerListener(mGraphView, 
-                mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
-                SensorManager.SENSOR_DELAY_FASTEST);
-    }
-    
-    @Override
-    protected void onStop() {
-        mSensorManager.unregisterListener(mGraphView);
-        super.onStop();
-    }
-}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls7.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls7.java
new file mode 100644
index 0000000..6243d3b
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls7.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 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;
+
+public class Controls7 extends Controls1 {}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls8.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls8.java
new file mode 100644
index 0000000..4dd4291
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls8.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 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;
+
+public class Controls8 extends Controls1 {}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/Controls9.java b/samples/ApiDemos/src/com/example/android/apis/view/Controls9.java
new file mode 100644
index 0000000..8a940aa
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/Controls9.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2014 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;
+
+public class Controls9 extends Controls1 {}
diff --git a/samples/browseable/BasicMediaDecoder/src/com.example.android.common.media/MediaCodecWrapper.java b/samples/browseable/BasicMediaDecoder/src/com.example.android.common.media/MediaCodecWrapper.java
index a511221..a483374 100644
--- a/samples/browseable/BasicMediaDecoder/src/com.example.android.common.media/MediaCodecWrapper.java
+++ b/samples/browseable/BasicMediaDecoder/src/com.example.android.common.media/MediaCodecWrapper.java
@@ -21,6 +21,7 @@
 import android.os.Looper;
 import android.view.Surface;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.util.ArrayDeque;
 import java.util.Queue;
@@ -136,7 +137,7 @@
      * @return
      */
     public static MediaCodecWrapper fromVideoFormat(final MediaFormat trackFormat,
-            Surface surface) {
+            Surface surface) throws IOException {
         MediaCodecWrapper result = null;
         MediaCodec videoCodec = null;
 
diff --git a/scripts/symbol.py b/scripts/symbol.py
index 0f58df6..a285fac 100755
--- a/scripts/symbol.py
+++ b/scripts/symbol.py
@@ -88,6 +88,11 @@
     known_toolchains = [
       ("i686-android-linux-4.4.3", "x86", "i686-android-linux")
     ]
+  elif ARCH == "mips":
+    gcc_version = os.environ["TARGET_GCC_VERSION"]
+    known_toolchains = [
+      ("mipsel-linux-android-" + gcc_version, "mips", "mipsel-linux-android")
+    ]
   else:
     known_toolchains = []
 
diff --git a/sdk/build_tools_source.prop_template b/sdk/build_tools_source.prop_template
index c9bfc2f..5d62307 100644
--- a/sdk/build_tools_source.prop_template
+++ b/sdk/build_tools_source.prop_template
@@ -1,3 +1,3 @@
 Pkg.UserSrc=false
-Pkg.Revision=${PLATFORM_SDK_VERSION}.0.2
+Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
 
diff --git a/sdk/doc_source.prop_template b/sdk/doc_source.prop_template
index 523d6bd..d3cdfd5 100644
--- a/sdk/doc_source.prop_template
+++ b/sdk/doc_source.prop_template
@@ -1,4 +1,4 @@
 Pkg.UserSrc=false
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
diff --git a/sdk/images_armeabi-v7a_source.prop_template b/sdk/images_armeabi-v7a_source.prop_template
index 4f2daac..86fc2a0 100644
--- a/sdk/images_armeabi-v7a_source.prop_template
+++ b/sdk/images_armeabi-v7a_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=armeabi-v7a
diff --git a/sdk/images_armeabi_source.prop_template b/sdk/images_armeabi_source.prop_template
index 906e378..8644d10 100644
--- a/sdk/images_armeabi_source.prop_template
+++ b/sdk/images_armeabi_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=armeabi
diff --git a/sdk/images_x86_source.prop_template b/sdk/images_x86_source.prop_template
index 90024ea..a587cd1 100644
--- a/sdk/images_x86_source.prop_template
+++ b/sdk/images_x86_source.prop_template
@@ -1,6 +1,6 @@
 Pkg.Desc=Android SDK Platform ${PLATFORM_VERSION}
 Pkg.UserSrc=false
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
 SystemImage.Abi=x86
diff --git a/sdk/plat_tools_source.prop_template b/sdk/plat_tools_source.prop_template
index b83af7f..5d62307 100644
--- a/sdk/plat_tools_source.prop_template
+++ b/sdk/plat_tools_source.prop_template
@@ -1,3 +1,3 @@
 Pkg.UserSrc=false
-Pkg.Revision=${PLATFORM_SDK_VERSION}.0.1
+Pkg.Revision=${PLATFORM_SDK_VERSION}.0.0
 
diff --git a/sdk/source_source.prop_template b/sdk/source_source.prop_template
index 523d6bd..d3cdfd5 100644
--- a/sdk/source_source.prop_template
+++ b/sdk/source_source.prop_template
@@ -1,4 +1,4 @@
 Pkg.UserSrc=false
-Pkg.Revision=2
+Pkg.Revision=1
 AndroidVersion.ApiLevel=${PLATFORM_SDK_VERSION}
 AndroidVersion.CodeName=${PLATFORM_VERSION_CODENAME}
diff --git a/sdk/support_source.prop_template b/sdk/support_source.prop_template
index f897712..ba7e6fb 100644
--- a/sdk/support_source.prop_template
+++ b/sdk/support_source.prop_template
@@ -1,5 +1,5 @@
 Pkg.UserSrc=false
-Pkg.Revision=${PLATFORM_SDK_VERSION}.0.1
+Pkg.Revision=${PLATFORM_SDK_VERSION}
 Extra.Vendor=android
 Extra.VendorId=android
 Extra.VendorDisplay=Android
diff --git a/testrunner/adb_interface.py b/testrunner/adb_interface.py
index fa394cd..dc43a93 100755
--- a/testrunner/adb_interface.py
+++ b/testrunner/adb_interface.py
@@ -506,3 +506,34 @@
   def GetSerialNumber(self):
     """Returns the serial number of the targeted device."""
     return self.SendCommand("get-serialno").strip()
+
+  def RuntimeReset(self, disable_keyguard=False, retry_count=3, preview_only=False):
+    """
+    Resets the Android runtime (does *not* reboot the kernel).
+
+    Blocks until the reset is complete and the package manager
+    is available.
+
+    Args:
+      disable_keyguard: if True, presses the MENU key to disable
+        key guard, after reset is finished
+      retry_count: number of times to retry reset before failing
+
+    Raises:
+      WaitForResponseTimedOutError if package manager does not respond
+      AbortError if unrecoverable error occurred
+    """
+
+    logger.Log("adb shell stop")
+    logger.Log("adb shell start")
+
+    if not preview_only:
+      self.SendShellCommand("stop", retry_count=retry_count)
+      self.SendShellCommand("start", retry_count=retry_count)
+
+    self.WaitForDevicePm()
+
+    if disable_keyguard:
+      logger.Log("input keyevent 82 ## disable keyguard")
+      if not preview_only:
+        self.SendShellCommand("input keyevent 82", retry_count=retry_count)
diff --git a/testrunner/android_build.py b/testrunner/android_build.py
index cacd67e..2baa5af 100644
--- a/testrunner/android_build.py
+++ b/testrunner/android_build.py
@@ -149,6 +149,25 @@
   return path
 
 
+def GetTargetNativeTestPath():
+  """Returns the full pathname to target/product data/nativetest/ directory.
+
+  Assumes build environment has been properly configured by envsetup &
+  lunch/choosecombo.
+
+  Returns:
+    The absolute file path of the Android target native test directory.
+
+  Raises:
+    AbortError: if Android target native test directory could not be found.
+  """
+  path = os.path.join(GetProductOut(), "data", "nativetest")
+  if not os.path.exists(path):
+    logger.Log("Error: Target native test path could not be found")
+    raise errors.AbortError
+  return path
+
+
 def GetTargetSystemBin():
   """Returns the full pathname to the target/product system/bin directory.
 
diff --git a/testrunner/runtest.py b/testrunner/runtest.py
index a76d9c0..9b83f57 100755
--- a/testrunner/runtest.py
+++ b/testrunner/runtest.py
@@ -73,11 +73,12 @@
   # default value for make -jX
   _DEFAULT_JOBS = 16
 
-  _DALVIK_VERIFIER_OFF_PROP = "dalvik.vm.dexopt-flags = v=n"
+  _DALVIK_VERIFIER_PROP = "dalvik.vm.dexopt-flags"
+  _DALVIK_VERIFIER_OFF_VALUE = "v=n"
+  _DALVIK_VERIFIER_OFF_PROP = "%s = %s" %(_DALVIK_VERIFIER_PROP, _DALVIK_VERIFIER_OFF_VALUE)
 
   # regular expression to match path to artifacts to install in make output
-  _RE_MAKE_INSTALL = re.compile(r'INSTALL-PATH:\s(.+)\s(.+)')
-
+  _RE_MAKE_INSTALL = re.compile(r'INSTALL-PATH:\s([^\s]+)\s(.*)$')
 
   def __init__(self):
     # disable logging of timestamp
@@ -113,6 +114,9 @@
     parser.add_option("-n", "--skip_execute", dest="preview", default=False,
                       action="store_true",
                       help="Do not execute, just preview commands")
+    parser.add_option("-i", "--build-install-only", dest="build_install_only", default=False,
+                      action="store_true",
+                      help="Do not execute, build tests and install to device only")
     parser.add_option("-r", "--raw-mode", dest="raw_mode", default=False,
                       action="store_true",
                       help="Raw mode (for output to other tools)")
@@ -193,7 +197,6 @@
       self._adb.SetDeviceTarget()
     elif self._options.serial is not None:
       self._adb.SetTargetSerial(self._options.serial)
-
     if self._options.verbose:
       logger.SetVerbose(True)
 
@@ -267,7 +270,9 @@
         target_tree.AddPath("external/emma")
 
       target_list = target_tree.GetPrunedMakeList()
+      target_dir_list = [re.sub(r'Android[.]mk$', r'', i) for i in target_list]
       target_build_string = " ".join(target_list)
+      target_dir_build_string = " ".join(target_dir_list)
       extra_args_string = " ".join(extra_args_set)
 
       # mmm cannot be used from python, so perform a similar operation using
@@ -275,9 +280,24 @@
       cmd = 'ONE_SHOT_MAKEFILE="%s" make -j%s -C "%s" GET-INSTALL-PATH all_modules %s' % (
           target_build_string, self._options.make_jobs, self._root_path,
           extra_args_string)
+      # mmma equivalent, used when regular mmm fails
+      alt_cmd = 'make -j%s -C "%s" -f build/core/main.mk %s all_modules BUILD_MODULES_IN_PATHS="%s"' % (
+              self._options.make_jobs, self._root_path, extra_args_string, target_dir_build_string)
+
       logger.Log(cmd)
       if not self._options.preview:
-        output = run_command.RunCommand(cmd, return_output=True, timeout_time=600)
+        run_command.SetAbortOnError()
+        try:
+          output = run_command.RunCommand(cmd, return_output=True, timeout_time=600)
+          ## Chances are this failed because it didn't build the dependencies
+        except errors.AbortError:
+          logger.Log("make failed. Trying to rebuild all dependencies.")
+          logger.Log("mmma -j%s %s" %(self._options.make_jobs, target_dir_build_string))
+          # Try again with mma equivalent, which will build the dependencies
+          run_command.RunCommand(alt_cmd, return_output=False, timeout_time=600)
+          # Run mmm again to get the install paths only
+          output = run_command.RunCommand(cmd, return_output=True, timeout_time=600)
+        run_command.SetAbortOnError(False)
         logger.SilentLog(output)
         self._DoInstall(output)
 
@@ -286,19 +306,25 @@
 
     Looks for 'install:' text from make output to find artifacts to install.
 
+    Files with the .apk extension get 'adb install'ed, all other files
+    get 'adb push'ed onto the device.
+
     Args:
       make_output: stdout from make command
     """
     for line in make_output.split("\n"):
       m = self._RE_MAKE_INSTALL.match(line)
       if m:
-        install_path = m.group(2)
-        if install_path.endswith(".apk"):
-          abs_install_path = os.path.join(self._root_path, install_path)
-          logger.Log("adb install -r %s" % abs_install_path)
-          logger.Log(self._adb.Install(abs_install_path))
-        else:
-          self._PushInstallFileToDevice(install_path)
+        # strip the 'INSTALL: <name>' from the left hand side
+        # the remaining string is a space-separated list of build-generated files
+        install_paths = m.group(2)
+        for install_path in re.split(r'\s+', install_paths):
+          if install_path.endswith(".apk"):
+            abs_install_path = os.path.join(self._root_path, install_path)
+            logger.Log("adb install -r %s" % abs_install_path)
+            logger.Log(self._adb.Install(abs_install_path))
+          else:
+            self._PushInstallFileToDevice(install_path)
 
   def _PushInstallFileToDevice(self, install_path):
     m = self._re_make_install_path.match(install_path)
@@ -406,7 +432,7 @@
     turns off verifier and reboots device to allow change to take effect.
     """
     # hack to check if these are frameworks/base tests. If so, turn off verifier
-    # to allow framework tests to access package-private framework api
+    # to allow framework tests to access private/protected/package-private framework api
     framework_test = False
     for test in test_list:
       if os.path.commonprefix([test.GetBuildPath(), "frameworks/base"]):
@@ -416,35 +442,54 @@
       # necessary
       output = self._adb.SendShellCommand("cat /data/local.prop")
       if not self._DALVIK_VERIFIER_OFF_PROP in output:
+
+        # Read the existing dalvik verifier flags.
+        old_prop_value = self._adb.SendShellCommand("getprop %s" \
+            %(self._DALVIK_VERIFIER_PROP))
+        old_prop_value = old_prop_value.strip() if old_prop_value else ""
+
+        # Append our verifier flags to existing flags
+        new_prop_value = "%s %s" %(self._DALVIK_VERIFIER_OFF_VALUE, old_prop_value)
+
+        # Update property now, as /data/local.prop is not read until reboot
+        logger.Log("adb shell setprop %s '%s'" \
+            %(self._DALVIK_VERIFIER_PROP, new_prop_value))
+        if not self._options.preview:
+          self._adb.SendShellCommand("setprop %s '%s'" \
+            %(self._DALVIK_VERIFIER_PROP, new_prop_value))
+
+        # Write prop to /data/local.prop
+        # Every time device is booted, it will pick up this value
+        new_prop_assignment = "%s = %s" %(self._DALVIK_VERIFIER_PROP, new_prop_value)
         if self._options.preview:
           logger.Log("adb shell \"echo %s >> /data/local.prop\""
-                     % self._DALVIK_VERIFIER_OFF_PROP)
+                     % new_prop_assignment)
           logger.Log("adb shell chmod 644 /data/local.prop")
-          logger.Log("adb reboot")
-          logger.Log("adb wait-for-device")
         else:
           logger.Log("Turning off dalvik verifier and rebooting")
           self._adb.SendShellCommand("\"echo %s >> /data/local.prop\""
-                                     % self._DALVIK_VERIFIER_OFF_PROP)
+                                     % new_prop_assignment)
 
-          self._ChmodReboot()
+        # Reset runtime so that dalvik picks up new verifier flags from prop
+        self._ChmodRuntimeReset()
       elif not self._options.preview:
         # check the permissions on the file
         permout = self._adb.SendShellCommand("ls -l /data/local.prop")
         if not "-rw-r--r--" in permout:
           logger.Log("Fixing permissions on /data/local.prop and rebooting")
-          self._ChmodReboot()
+          self._ChmodRuntimeReset()
 
-  def _ChmodReboot(self):
-    """Perform a chmod of /data/local.prop and reboot.
+  def _ChmodRuntimeReset(self):
+    """Perform a chmod of /data/local.prop and reset the runtime.
     """
-    self._adb.SendShellCommand("chmod 644 /data/local.prop")
-    self._adb.SendCommand("reboot")
-    # wait for device to go offline
-    time.sleep(10)
-    self._adb.SendCommand("wait-for-device", timeout_time=60,
-                          retry_count=3)
-    self._adb.EnableAdbRoot()
+    logger.Log("adb shell chmod 644 /data/local.prop ## u+w,a+r")
+    if not self._options.preview:
+      self._adb.SendShellCommand("chmod 644 /data/local.prop")
+
+    self._adb.RuntimeReset(preview_only=self._options.preview)
+
+    if not self._options.preview:
+      self._adb.EnableAdbRoot()
 
 
   def RunTests(self):
@@ -459,6 +504,10 @@
       if not self._options.skip_build:
         self._DoBuild()
 
+      if self._options.build_install_only:
+        logger.Log("Skipping test execution (due to --build-install-only flag)")
+        return
+
       for test_suite in self._GetTestsToRun():
         try:
           test_suite.Run(self._options, self._adb)
diff --git a/testrunner/test_defs.xml b/testrunner/test_defs.xml
index 421641f..e0b5259 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -132,10 +132,6 @@
     build_path="frameworks/base/libs/androidfw/tests"
     description="Framework libandroidfw unit tests." />
 
-<test-native name="libutils"
-    build_path="frameworks/native/libs/utils/tests"
-    description="Framework libutils unit tests." />
-
 <test-native name="libinput"
     build_path="frameworks/native/libs/input/tests"
     description="Framework libinput unit tests." />
diff --git a/testrunner/test_defs/gtest.py b/testrunner/test_defs/gtest.py
index dc72f94..cceead9 100644
--- a/testrunner/test_defs/gtest.py
+++ b/testrunner/test_defs/gtest.py
@@ -73,6 +73,7 @@
       - test_*.[c|cc|cpp]
       - *_test.[c|cc|cpp]
       - *_unittest.[c|cc|cpp]
+      - *Tests.[cc|cpp]
 
     """
     if not sub_tests_path:
@@ -101,6 +102,7 @@
       - test_*.[cc|cpp]
       - *_test.[cc|cpp]
       - *_unittest.[cc|cpp]
+      - *Tests.[cc|cpp]
 
     This method is a callback for os.path.walk.
 
@@ -115,6 +117,6 @@
   def _EvaluateFile(self, test_list, file):
     (name, ext) = os.path.splitext(file)
     if ext == ".cc" or ext == ".cpp" or ext == ".c":
-      if re.search("_test$|_test_$|_unittest$|_unittest_$|^test_", name):
+      if re.search("_test$|_test_$|_unittest$|_unittest_$|^test_|Tests$", name):
         logger.SilentLog("Found native test file %s" % file)
         test_list.append(name)
diff --git a/testrunner/test_defs/native_test.py b/testrunner/test_defs/native_test.py
index caef877..f1ae82c 100644
--- a/testrunner/test_defs/native_test.py
+++ b/testrunner/test_defs/native_test.py
@@ -60,8 +60,8 @@
     host_list = self._FilterOutMissing(android_build.GetHostBin(), source_list)
     logger.SilentLog("Host tests %s" % host_list)
 
-    # Target tests are under $ANDROID_PRODUCT_OUT/system/bin.
-    target_list = self._FilterOutMissing(android_build.GetTargetSystemBin(),
+    # Target tests are under $ANDROID_PRODUCT_OUT/data/nativetest.
+    target_list = self._FilterOutMissing(android_build.GetTargetNativeTestPath(),
                                          source_list)
     logger.SilentLog("Target tests %s" % target_list)
 
@@ -82,7 +82,7 @@
     # Run on the device
     logger.Log("\nRunning on target")
     for f in target_list:
-      full_path = os.path.join(os.sep, "system", "bin", f)
+      full_path = os.path.join(os.sep, "data", "nativetest", f)
 
       # Single quotes are needed to prevent the shell splitting it.
       output = adb.SendShellCommand("'%s 2>&1;echo -n exit code:$?'" %
@@ -132,17 +132,38 @@
       path: Where the binaries should be.
       sources: List of tests source path.
     Returns:
-      A list of test binaries built from the sources.
+      A list of relative paths to the test binaries built from the sources.
     """
     binaries = []
     for f in sources:
       binary = os.path.basename(f)
       binary = os.path.splitext(binary)[0]
-      full_path = os.path.join(path, binary)
-      if os.path.exists(full_path):
+      found = self._FindFileRecursively(path, binary)
+      if found:
+        binary = os.path.relpath(os.path.abspath(found),
+                                 os.path.abspath(path))
         binaries.append(binary)
     return binaries
 
+  def _FindFileRecursively(self, path, match):
+    """Finds the first executable binary in a given path that matches the name.
+
+    Args:
+      path: Where to search for binaries. Can be nested directories.
+      binary: Which binary to search for.
+    Returns:
+      first matched file in the path or None if none is found.
+    """
+    for root, dirs, files in os.walk(path):
+      for f in files:
+        if f == match:
+          return os.path.join(root, f)
+      for d in dirs:
+        found = self._FindFileRecursively(os.path.join(root, d), match)
+        if found:
+          return found
+    return None
+
   def _RunHostCommand(self, binary, valgrind=False):
     """Run a command on the host (opt using valgrind).
 
diff --git a/tools/emulator/test-apps/GpsLocationTest/Android.mk b/tools/emulator/test-apps/GpsLocationTest/Android.mk
deleted file mode 100644
index 5f90f3a..0000000
--- a/tools/emulator/test-apps/GpsLocationTest/Android.mk
+++ /dev/null
@@ -1,32 +0,0 @@
-# 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.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-# Only compile source java files in this apk.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_PACKAGE_NAME := GpsLocationTest
-
-LOCAL_SDK_VERSION := 4
-
-LOCAL_PROGUARD_ENABLED := disabled
-
-include $(BUILD_PACKAGE)
-
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/tools/emulator/test-apps/GpsLocationTest/AndroidManifest.xml b/tools/emulator/test-apps/GpsLocationTest/AndroidManifest.xml
deleted file mode 100644
index 901855e..0000000
--- a/tools/emulator/test-apps/GpsLocationTest/AndroidManifest.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-<?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.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="com.android.emulator.gps.test"
-      android:versionCode="1"
-      android:versionName="1.0">
-    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
-    <uses-sdk android:minSdkVersion="4" />
-    <instrumentation android:targetPackage="com.android.emulator.gps.test"
-                     android:name="android.test.InstrumentationTestRunner" />
-    <application  android:label="GPS Location Test">
-        <uses-library android:name="android.test.runner" />
-    </application>
-</manifest>
\ No newline at end of file
diff --git a/tools/emulator/test-apps/ConnectivityTest/Android.mk b/tools/emulator/test-apps/SmokeTests/Android.mk
similarity index 80%
rename from tools/emulator/test-apps/ConnectivityTest/Android.mk
rename to tools/emulator/test-apps/SmokeTests/Android.mk
index ca20d57..ccd3eb4 100644
--- a/tools/emulator/test-apps/ConnectivityTest/Android.mk
+++ b/tools/emulator/test-apps/SmokeTests/Android.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2011 The Android Open Source Project
+# Copyright (C) 2014 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.
@@ -15,18 +15,18 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
+LOCAL_STATIC_JAVA_LIBRARIES := android-support-test
+
 LOCAL_MODULE_TAGS := optional
 
 # Only compile source java files in this apk.
 LOCAL_SRC_FILES := $(call all-java-files-under, src)
 
-LOCAL_PACKAGE_NAME := ConnectivityTest
+LOCAL_PACKAGE_NAME := EmulatorSmokeTests
 
 LOCAL_SDK_VERSION := 4
 
 LOCAL_PROGUARD_ENABLED := disabled
 
-include $(BUILD_PACKAGE)
 
-# Use the following include to make our test apk.
-include $(call all-makefiles-under,$(LOCAL_PATH))
+include $(BUILD_PACKAGE)
diff --git a/tools/emulator/test-apps/ConnectivityTest/AndroidManifest.xml b/tools/emulator/test-apps/SmokeTests/AndroidManifest.xml
similarity index 70%
rename from tools/emulator/test-apps/ConnectivityTest/AndroidManifest.xml
rename to tools/emulator/test-apps/SmokeTests/AndroidManifest.xml
index 80f65cf..8843a00 100644
--- a/tools/emulator/test-apps/ConnectivityTest/AndroidManifest.xml
+++ b/tools/emulator/test-apps/SmokeTests/AndroidManifest.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!-- Copyright (C) 2014 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.
@@ -14,14 +14,14 @@
      limitations under the License.
 -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="com.android.emulator.connectivity.test"
-      android:versionCode="1"
-      android:versionName="1.0">
+      package="com.android.emulator.smoketests">
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.READ_SMS" />
     <uses-sdk android:minSdkVersion="4" />
-    <instrumentation android:targetPackage="com.android.emulator.connectivity.test" android:name="android.test.InstrumentationTestRunner" />
-    <application  android:label="Connectivity Test">
-        <uses-library android:name="android.test.runner" />
+    <instrumentation android:targetPackage="com.android.emulator.smoketests"
+                     android:name="android.support.test.runner.AndroidJUnitRunner" />
+    <application  android:label="Emulator Smoke Tests">
     </application>
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/tools/emulator/test-apps/ConnectivityTest/src/com/android/emulator/connectivity/test/ConnectivityTest.java b/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/connectivity/ConnectivityTest.java
similarity index 97%
rename from tools/emulator/test-apps/ConnectivityTest/src/com/android/emulator/connectivity/test/ConnectivityTest.java
rename to tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/connectivity/ConnectivityTest.java
index 9931eb8..9fe1ebe 100644
--- a/tools/emulator/test-apps/ConnectivityTest/src/com/android/emulator/connectivity/test/ConnectivityTest.java
+++ b/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/connectivity/ConnectivityTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.emulator.connectivity.test;
+package com.android.emulator.smoketests.connectivity;
 
 import java.io.IOException;
 import java.net.URL;
diff --git a/tools/emulator/test-apps/GpsLocationTest/src/com/android/emulator/gps/test/GpsLocationTest.java b/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/gps/GpsLocationTest.java
similarity index 98%
rename from tools/emulator/test-apps/GpsLocationTest/src/com/android/emulator/gps/test/GpsLocationTest.java
rename to tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/gps/GpsLocationTest.java
index 6eb3834..1e0258c 100644
--- a/tools/emulator/test-apps/GpsLocationTest/src/com/android/emulator/gps/test/GpsLocationTest.java
+++ b/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/gps/GpsLocationTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.emulator.gps.test;
+package com.android.emulator.smoketests.gps;
 
 import android.content.Context;
 import android.location.Location;
diff --git a/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/sms/SmsTest.java b/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/sms/SmsTest.java
new file mode 100644
index 0000000..2e18cc4
--- /dev/null
+++ b/tools/emulator/test-apps/SmokeTests/src/com/android/emulator/smoketests/sms/SmsTest.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2014 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.android.emulator.smoketests.sms;
+
+import android.content.Context;
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.os.HandlerThread;
+import android.support.test.InjectContext;
+
+import org.junit.Assert;
+import static junit.framework.Assert.assertEquals;
+
+import org.junit.Test;
+/**
+ * Sms Test
+ *
+ * Test that an SMS message has been received
+ */
+public class SmsTest {
+
+    /**
+     * Prior to running this test an sms must be sent
+     * via DDMS
+     */
+    public final static String NUMBER = "5551212";
+    public final static String BODY = "test sms";
+    private final static int SMS_POLL_TIME_MS = 10 * 1000;
+    private final static int SIXY_SECONDS_OF_LOOPS = 6;
+    @InjectContext
+    public Context mContext;
+
+    /**
+     * Verify that an SMS has been received with the correct number and body
+     */
+    @Test
+    public void testReceivedSms() throws java.lang.InterruptedException {
+        Cursor c = getSmsCursor();
+        c.moveToFirst();
+
+        String number = c.getString(c.getColumnIndexOrThrow("address"));
+        String body = c.getString(c.getColumnIndexOrThrow("body"));
+
+        c.close();
+
+        assertEquals(NUMBER, number);
+        assertEquals(BODY, body);
+    }
+
+    private Cursor getSmsCursor() throws java.lang.InterruptedException {
+        ContentResolver r = mContext.getContentResolver();
+        Uri message = Uri.parse("content://sms/");
+        Cursor c;
+
+        for(int i = 0; i < SIXY_SECONDS_OF_LOOPS; i++) {
+            c = r.query(message,null,null,null,null);
+
+            if(c.getCount() != 0) {
+                return c;
+            }
+
+            c.close();
+            Thread.sleep(SMS_POLL_TIME_MS);
+        }
+        Assert.fail("Did not find any SMS messages. Giving up");
+        // necessary for compilation
+        return null;
+    }
+
+}
diff --git a/tools/recovery_l10n/res/values-be/strings.xml b/tools/recovery_l10n/res/values-az-rAZ/strings.xml
similarity index 61%
copy from tools/recovery_l10n/res/values-be/strings.xml
copy to tools/recovery_l10n/res/values-az-rAZ/strings.xml
index 5f48a2d..3435573 100644
--- a/tools/recovery_l10n/res/values-be/strings.xml
+++ b/tools/recovery_l10n/res/values-az-rAZ/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recovery_installing" msgid="7864047928003865598">"Усталёўка абнаўлення сістэмы..."</string>
-    <string name="recovery_erasing" msgid="4612809744968710197">"Выдаленне..."</string>
-    <string name="recovery_no_command" msgid="1915703879031023455">"Няма каманды"</string>
-    <string name="recovery_error" msgid="4550265746256727080">"Памылка"</string>
+    <string name="recovery_installing" msgid="7864047928003865598">"Sistem güncəlləməsi quraşdırılır..."</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"Silinir..."</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"Əmr yoxdur."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"Xəta!"</string>
 </resources>
diff --git a/tools/recovery_l10n/res/values-be/strings.xml b/tools/recovery_l10n/res/values-az/strings.xml
similarity index 61%
copy from tools/recovery_l10n/res/values-be/strings.xml
copy to tools/recovery_l10n/res/values-az/strings.xml
index 5f48a2d..3435573 100644
--- a/tools/recovery_l10n/res/values-be/strings.xml
+++ b/tools/recovery_l10n/res/values-az/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recovery_installing" msgid="7864047928003865598">"Усталёўка абнаўлення сістэмы..."</string>
-    <string name="recovery_erasing" msgid="4612809744968710197">"Выдаленне..."</string>
-    <string name="recovery_no_command" msgid="1915703879031023455">"Няма каманды"</string>
-    <string name="recovery_error" msgid="4550265746256727080">"Памылка"</string>
+    <string name="recovery_installing" msgid="7864047928003865598">"Sistem güncəlləməsi quraşdırılır..."</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"Silinir..."</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"Əmr yoxdur."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"Xəta!"</string>
 </resources>
diff --git a/tools/recovery_l10n/res/values-be/strings.xml b/tools/recovery_l10n/res/values-en-rIN/strings.xml
similarity index 61%
copy from tools/recovery_l10n/res/values-be/strings.xml
copy to tools/recovery_l10n/res/values-en-rIN/strings.xml
index 5f48a2d..b70d678c 100644
--- a/tools/recovery_l10n/res/values-be/strings.xml
+++ b/tools/recovery_l10n/res/values-en-rIN/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recovery_installing" msgid="7864047928003865598">"Усталёўка абнаўлення сістэмы..."</string>
-    <string name="recovery_erasing" msgid="4612809744968710197">"Выдаленне..."</string>
-    <string name="recovery_no_command" msgid="1915703879031023455">"Няма каманды"</string>
-    <string name="recovery_error" msgid="4550265746256727080">"Памылка"</string>
+    <string name="recovery_installing" msgid="7864047928003865598">"Installing system update…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"Erasing…"</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"No command."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"Error!"</string>
 </resources>
diff --git a/tools/recovery_l10n/res/values-et/strings.xml b/tools/recovery_l10n/res/values-et-rEE/strings.xml
similarity index 100%
rename from tools/recovery_l10n/res/values-et/strings.xml
rename to tools/recovery_l10n/res/values-et-rEE/strings.xml
diff --git a/tools/recovery_l10n/res/values-be/strings.xml b/tools/recovery_l10n/res/values-fr-rCA/strings.xml
similarity index 61%
copy from tools/recovery_l10n/res/values-be/strings.xml
copy to tools/recovery_l10n/res/values-fr-rCA/strings.xml
index 5f48a2d..f2a85d8 100644
--- a/tools/recovery_l10n/res/values-be/strings.xml
+++ b/tools/recovery_l10n/res/values-fr-rCA/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recovery_installing" msgid="7864047928003865598">"Усталёўка абнаўлення сістэмы..."</string>
-    <string name="recovery_erasing" msgid="4612809744968710197">"Выдаленне..."</string>
-    <string name="recovery_no_command" msgid="1915703879031023455">"Няма каманды"</string>
-    <string name="recovery_error" msgid="4550265746256727080">"Памылка"</string>
+    <string name="recovery_installing" msgid="7864047928003865598">"Installation de la mise à jour du système en cours…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"Effacement en cours…"</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"Aucune commande."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"Erreur!"</string>
 </resources>
diff --git a/tools/recovery_l10n/res/values-hi/strings.xml b/tools/recovery_l10n/res/values-hi/strings.xml
index 3dfab3e..a470d12 100644
--- a/tools/recovery_l10n/res/values-hi/strings.xml
+++ b/tools/recovery_l10n/res/values-hi/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recovery_installing" msgid="7864047928003865598">"सिस्टम अपडेट इंस्टॉल कर रहा है…"</string>
+    <string name="recovery_installing" msgid="7864047928003865598">"सिस्टम के बारे में नई जानकारी मिल रही है…"</string>
     <string name="recovery_erasing" msgid="4612809744968710197">"मिटा रहा है…"</string>
     <string name="recovery_no_command" msgid="1915703879031023455">"कोई आदेश नहीं."</string>
     <string name="recovery_error" msgid="4550265746256727080">"त्रुटि!"</string>
diff --git a/tools/recovery_l10n/res/values-be/strings.xml b/tools/recovery_l10n/res/values-hy-rAM/strings.xml
similarity index 61%
copy from tools/recovery_l10n/res/values-be/strings.xml
copy to tools/recovery_l10n/res/values-hy-rAM/strings.xml
index 5f48a2d..7babe80 100644
--- a/tools/recovery_l10n/res/values-be/strings.xml
+++ b/tools/recovery_l10n/res/values-hy-rAM/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recovery_installing" msgid="7864047928003865598">"Усталёўка абнаўлення сістэмы..."</string>
-    <string name="recovery_erasing" msgid="4612809744968710197">"Выдаленне..."</string>
-    <string name="recovery_no_command" msgid="1915703879031023455">"Няма каманды"</string>
-    <string name="recovery_error" msgid="4550265746256727080">"Памылка"</string>
+    <string name="recovery_installing" msgid="7864047928003865598">"Համակարգի թարմացման տեղադրում…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"Ջնջում…"</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"Հրամանը տրված չէ:"</string>
+    <string name="recovery_error" msgid="4550265746256727080">"Սխալ"</string>
 </resources>
diff --git a/tools/recovery_l10n/res/values-ka-rGE/strings.xml b/tools/recovery_l10n/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..2d27c17
--- /dev/null
+++ b/tools/recovery_l10n/res/values-ka-rGE/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="recovery_installing" msgid="7864047928003865598">"სისტემის განახლების დაყენება…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"მიმდინარეობს წაშლა…"</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"ბრძანება არ არის."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"შეცდომა!"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-km-rKH/strings.xml b/tools/recovery_l10n/res/values-km-rKH/strings.xml
new file mode 100644
index 0000000..0c1c272
--- /dev/null
+++ b/tools/recovery_l10n/res/values-km-rKH/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="recovery_installing" msgid="7864047928003865598">"កំពុង​ដំឡើង​បច្ចុប្បន្នភាព​ប្រព័ន្ធ…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"កំពុង​លុប…"</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"គ្មាន​ពាក្យ​បញ្ជា។"</string>
+    <string name="recovery_error" msgid="4550265746256727080">"កំហុស!"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-lo-rLA/strings.xml b/tools/recovery_l10n/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..5880cca
--- /dev/null
+++ b/tools/recovery_l10n/res/values-lo-rLA/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="recovery_installing" msgid="7864047928003865598">"ກຳລັງຕິດຕັ້ງການອັບເດດລະບົບ..."</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"ກຳລັງລຶບ..."</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"ບໍ່ມີຄຳສັ່ງ."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"ຜິດພາດ!"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-be/strings.xml b/tools/recovery_l10n/res/values-mn-rMN/strings.xml
similarity index 69%
rename from tools/recovery_l10n/res/values-be/strings.xml
rename to tools/recovery_l10n/res/values-mn-rMN/strings.xml
index 5f48a2d..463cafe 100644
--- a/tools/recovery_l10n/res/values-be/strings.xml
+++ b/tools/recovery_l10n/res/values-mn-rMN/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recovery_installing" msgid="7864047928003865598">"Усталёўка абнаўлення сістэмы..."</string>
-    <string name="recovery_erasing" msgid="4612809744968710197">"Выдаленне..."</string>
-    <string name="recovery_no_command" msgid="1915703879031023455">"Няма каманды"</string>
-    <string name="recovery_error" msgid="4550265746256727080">"Памылка"</string>
+    <string name="recovery_installing" msgid="7864047928003865598">"Системийн шинэчлэлтийг суулгаж байна…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"Арилгаж байна…"</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"Команд байхгүй."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"Алдаа!"</string>
 </resources>
diff --git a/tools/recovery_l10n/res/values-ms/strings.xml b/tools/recovery_l10n/res/values-ms-rMY/strings.xml
similarity index 100%
rename from tools/recovery_l10n/res/values-ms/strings.xml
rename to tools/recovery_l10n/res/values-ms-rMY/strings.xml
diff --git a/tools/recovery_l10n/res/values-ne-rNP/strings.xml b/tools/recovery_l10n/res/values-ne-rNP/strings.xml
new file mode 100644
index 0000000..835f275
--- /dev/null
+++ b/tools/recovery_l10n/res/values-ne-rNP/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="recovery_installing" msgid="7864047928003865598">"प्रणाली अद्यावधिक स्थापना गर्दै..."</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"मेटाइदै..."</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"कुनै आदेश छैन।"</string>
+    <string name="recovery_error" msgid="4550265746256727080">"त्रुटि!"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-ne/strings.xml b/tools/recovery_l10n/res/values-ne/strings.xml
new file mode 100644
index 0000000..835f275
--- /dev/null
+++ b/tools/recovery_l10n/res/values-ne/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="recovery_installing" msgid="7864047928003865598">"प्रणाली अद्यावधिक स्थापना गर्दै..."</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"मेटाइदै..."</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"कुनै आदेश छैन।"</string>
+    <string name="recovery_error" msgid="4550265746256727080">"त्रुटि!"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-si-rLK/strings.xml b/tools/recovery_l10n/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..e717a97
--- /dev/null
+++ b/tools/recovery_l10n/res/values-si-rLK/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="recovery_installing" msgid="7864047928003865598">"පද්ධති යාවත්කාල ස්ථාපනය කරමින්…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"මකමින්...."</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"විධානයක් නොමැත."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"දෝෂය!"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-si/strings.xml b/tools/recovery_l10n/res/values-si/strings.xml
new file mode 100644
index 0000000..e717a97
--- /dev/null
+++ b/tools/recovery_l10n/res/values-si/strings.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="recovery_installing" msgid="7864047928003865598">"පද්ධති යාවත්කාල ස්ථාපනය කරමින්…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"මකමින්...."</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"විධානයක් නොමැත."</string>
+    <string name="recovery_error" msgid="4550265746256727080">"දෝෂය!"</string>
+</resources>
diff --git a/tools/recovery_l10n/res/values-be/strings.xml b/tools/recovery_l10n/res/values-zh-rHK/strings.xml
similarity index 61%
copy from tools/recovery_l10n/res/values-be/strings.xml
copy to tools/recovery_l10n/res/values-zh-rHK/strings.xml
index 5f48a2d..f615c7a 100644
--- a/tools/recovery_l10n/res/values-be/strings.xml
+++ b/tools/recovery_l10n/res/values-zh-rHK/strings.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recovery_installing" msgid="7864047928003865598">"Усталёўка абнаўлення сістэмы..."</string>
-    <string name="recovery_erasing" msgid="4612809744968710197">"Выдаленне..."</string>
-    <string name="recovery_no_command" msgid="1915703879031023455">"Няма каманды"</string>
-    <string name="recovery_error" msgid="4550265746256727080">"Памылка"</string>
+    <string name="recovery_installing" msgid="7864047928003865598">"正在安裝系統更新…"</string>
+    <string name="recovery_erasing" msgid="4612809744968710197">"正在清除…"</string>
+    <string name="recovery_no_command" msgid="1915703879031023455">"沒有指令。"</string>
+    <string name="recovery_error" msgid="4550265746256727080">"錯誤!"</string>
 </resources>
diff --git a/tools/rmtypedefs/.gitignore b/tools/rmtypedefs/.gitignore
new file mode 100644
index 0000000..04d423f
--- /dev/null
+++ b/tools/rmtypedefs/.gitignore
@@ -0,0 +1,3 @@
+out
+.idea/workspace.xml
+.DS_Store
diff --git a/tools/rmtypedefs/.idea/compiler.xml b/tools/rmtypedefs/.idea/compiler.xml
new file mode 100644
index 0000000..217af47
--- /dev/null
+++ b/tools/rmtypedefs/.idea/compiler.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="CompilerConfiguration">
+    <option name="DEFAULT_COMPILER" value="Javac" />
+    <resourceExtensions />
+    <wildcardResourcePatterns>
+      <entry name="!?*.java" />
+      <entry name="!?*.form" />
+      <entry name="!?*.class" />
+      <entry name="!?*.groovy" />
+      <entry name="!?*.scala" />
+      <entry name="!?*.flex" />
+      <entry name="!?*.kt" />
+      <entry name="!?*.clj" />
+    </wildcardResourcePatterns>
+    <annotationProcessing>
+      <profile default="true" name="Default" enabled="false">
+        <processorPath useClasspath="true" />
+      </profile>
+    </annotationProcessing>
+  </component>
+</project>
+
diff --git a/tools/rmtypedefs/.idea/copyright/profiles_settings.xml b/tools/rmtypedefs/.idea/copyright/profiles_settings.xml
new file mode 100644
index 0000000..3572571
--- /dev/null
+++ b/tools/rmtypedefs/.idea/copyright/profiles_settings.xml
@@ -0,0 +1,5 @@
+<component name="CopyrightManager">
+  <settings default="">
+    <module2copyright />
+  </settings>
+</component>
\ No newline at end of file
diff --git a/tools/rmtypedefs/.idea/encodings.xml b/tools/rmtypedefs/.idea/encodings.xml
new file mode 100644
index 0000000..e206d70
--- /dev/null
+++ b/tools/rmtypedefs/.idea/encodings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
+</project>
+
diff --git a/tools/rmtypedefs/.idea/misc.xml b/tools/rmtypedefs/.idea/misc.xml
new file mode 100644
index 0000000..9732041
--- /dev/null
+++ b/tools/rmtypedefs/.idea/misc.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="EntryPointsManager">
+    <entry_points version="2.0" />
+  </component>
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_6" assert-keyword="true" jdk-15="true" project-jdk-name="1.6" project-jdk-type="JavaSDK">
+    <output url="file://$PROJECT_DIR$/out" />
+  </component>
+</project>
+
diff --git a/tools/rmtypedefs/.idea/modules.xml b/tools/rmtypedefs/.idea/modules.xml
new file mode 100644
index 0000000..52f04c3
--- /dev/null
+++ b/tools/rmtypedefs/.idea/modules.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/rmtypedefs.iml" filepath="$PROJECT_DIR$/rmtypedefs.iml" />
+    </modules>
+  </component>
+</project>
+
diff --git a/tools/rmtypedefs/.idea/scopes/scope_settings.xml b/tools/rmtypedefs/.idea/scopes/scope_settings.xml
new file mode 100644
index 0000000..922003b
--- /dev/null
+++ b/tools/rmtypedefs/.idea/scopes/scope_settings.xml
@@ -0,0 +1,5 @@
+<component name="DependencyValidationManager">
+  <state>
+    <option name="SKIP_IMPORT_STATEMENTS" value="false" />
+  </state>
+</component>
\ No newline at end of file
diff --git a/tools/rmtypedefs/.idea/uiDesigner.xml b/tools/rmtypedefs/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/tools/rmtypedefs/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Palette2">
+    <group name="Swing">
+      <item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
+      </item>
+      <item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
+        <default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
+        <initial-values>
+          <property name="text" value="Button" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="RadioButton" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="CheckBox" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
+        <initial-values>
+          <property name="text" value="Label" />
+        </initial-values>
+      </item>
+      <item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
+          <preferred-size width="150" height="-1" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
+          <preferred-size width="150" height="50" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
+          <preferred-size width="200" height="200" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
+      </item>
+      <item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
+      </item>
+      <item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
+          <preferred-size width="-1" height="20" />
+        </default-constraints>
+      </item>
+      <item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
+        <default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
+      </item>
+      <item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
+        <default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
+      </item>
+    </group>
+  </component>
+</project>
+
diff --git a/tools/rmtypedefs/.idea/vcs.xml b/tools/rmtypedefs/.idea/vcs.xml
new file mode 100644
index 0000000..a5dd086
--- /dev/null
+++ b/tools/rmtypedefs/.idea/vcs.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="" vcs="" />
+    <mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
+  </component>
+</project>
+
diff --git a/tools/rmtypedefs/Android.mk b/tools/rmtypedefs/Android.mk
new file mode 100644
index 0000000..d79d2ff
--- /dev/null
+++ b/tools/rmtypedefs/Android.mk
@@ -0,0 +1,46 @@
+# Copyright (C) 2013 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.
+
+LOCAL_PATH := $(call my-dir)
+
+# We use copy-file-to-new-target so that the installed
+# script file's timestamp is at least as new as the
+# .jar file it wraps.
+
+# the execution script
+# ============================================================
+include $(CLEAR_VARS)
+LOCAL_IS_HOST_MODULE := true
+LOCAL_MODULE_CLASS := EXECUTABLES
+LOCAL_MODULE := rmtypedefs
+
+#LOCAL_STATIC_JAVA_LIBRARIES := \
+#        asm-tools \
+#        guavalib
+
+include $(BUILD_SYSTEM)/base_rules.mk
+
+$(LOCAL_BUILT_MODULE): $(HOST_OUT_JAVA_LIBRARIES)/rmtypedefs$(COMMON_JAVA_PACKAGE_SUFFIX)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/etc/rmtypedefs | $(ACP)
+	@echo "Copy: $(PRIVATE_MODULE) ($@)"
+	$(copy-file-to-new-target)
+	$(hide) chmod 755 $@
+
+# the other stuff
+# ============================================================
+subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \
+		src \
+	))
+
+include $(subdirs)
diff --git a/tools/rmtypedefs/README.txt b/tools/rmtypedefs/README.txt
new file mode 100644
index 0000000..9f3fb8b
--- /dev/null
+++ b/tools/rmtypedefs/README.txt
@@ -0,0 +1,13 @@
+Android TypeDef Remover 1.0
+
+This utility finds and removes all .class files that have been
+annotated with the @IntDef annotation (android.annotations.IntDef) or
+the @StringDef annotation (android.annotations.StringDef).
+
+It also makes sure that these annotations have source level retention
+(@Retention(RetentionPolicy.SOURCE)), since otherwise uses of the
+typedef will appear in .class files as well.
+
+This is intended to be used during the build to strip out any typedef
+annotation classes, since these are not needed (or desirable) in the
+system image.
diff --git a/tools/rmtypedefs/etc/manifest.txt b/tools/rmtypedefs/etc/manifest.txt
new file mode 100644
index 0000000..39f2e29
--- /dev/null
+++ b/tools/rmtypedefs/etc/manifest.txt
@@ -0,0 +1,2 @@
+Manifest-Version: 1.0
+Main-Class: com.android.tools.rmtypedefs.RmTypeDefs
diff --git a/tools/rmtypedefs/etc/rmtypedefs b/tools/rmtypedefs/etc/rmtypedefs
new file mode 100755
index 0000000..bc0cbe2
--- /dev/null
+++ b/tools/rmtypedefs/etc/rmtypedefs
@@ -0,0 +1,46 @@
+#!/bin/bash
+#
+# Copyright (C) 2013 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 up prog to be the path of this script, including following symlinks,
+# and set up progdir to be the fully-qualified pathname of its directory.
+prog="$0"
+while [ -h "${prog}" ]; do
+    newProg=`/bin/ls -ld "${prog}"`
+    newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
+    if expr "x${newProg}" : 'x/' >/dev/null; then
+        prog="${newProg}"
+    else
+        progdir=`dirname "${prog}"`
+        prog="${progdir}/${newProg}"
+    fi
+done
+oldwd=`pwd`
+progdir=`dirname "${prog}"`
+cd "${progdir}"
+progdir=`pwd`
+prog="${progdir}"/`basename "${prog}"`
+cd "${oldwd}"
+
+libdir=`dirname $progdir`/framework
+
+javaOpts=""
+while expr "x$1" : 'x-J' >/dev/null; do
+    opt=`expr "$1" : '-J\(.*\)'`
+    javaOpts="${javaOpts} -${opt}"
+    shift
+done
+
+exec java $javaOpts -jar $libdir/rmtypedefs.jar "$@"
diff --git a/tools/rmtypedefs/rmtypedefs.iml b/tools/rmtypedefs/rmtypedefs.iml
new file mode 100644
index 0000000..6e0f0fc
--- /dev/null
+++ b/tools/rmtypedefs/rmtypedefs.iml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="false">
+    <output url="file://$MODULE_DIR$/../../../out/rmtypedefs" />
+    <output-test url="file://$MODULE_DIR$/../../../out/rmtypedefs" />
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/asm-tools/asm-4.0.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/asm-tools/src-4.0.zip!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+    <orderEntry type="module-library">
+      <library>
+        <CLASSES>
+          <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/guava-tools/guava-13.0.1.jar!/" />
+        </CLASSES>
+        <JAVADOC />
+        <SOURCES>
+          <root url="jar://$MODULE_DIR$/../../../prebuilts/tools/common/guava-tools/src.zip!/" />
+        </SOURCES>
+      </library>
+    </orderEntry>
+  </component>
+</module>
+
diff --git a/tools/rmtypedefs/src/Android.mk b/tools/rmtypedefs/src/Android.mk
new file mode 100644
index 0000000..067a2e6
--- /dev/null
+++ b/tools/rmtypedefs/src/Android.mk
@@ -0,0 +1,31 @@
+# Copyright (C) 2013 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.
+
+LOCAL_PATH := $(call my-dir)
+
+
+# rmtypedefs java library
+# ============================================================
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+LOCAL_JAR_MANIFEST := ../etc/manifest.txt
+LOCAL_STATIC_JAVA_LIBRARIES := \
+        asm-tools \
+        guava-tools
+
+LOCAL_MODULE:= rmtypedefs
+
+include $(BUILD_HOST_JAVA_LIBRARY)
+
diff --git a/tools/rmtypedefs/src/com/android/tools/rmtypedefs/RmTypeDefs.java b/tools/rmtypedefs/src/com/android/tools/rmtypedefs/RmTypeDefs.java
new file mode 100644
index 0000000..9375590
--- /dev/null
+++ b/tools/rmtypedefs/src/com/android/tools/rmtypedefs/RmTypeDefs.java
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2013 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.android.tools.rmtypedefs;
+
+import com.google.common.io.Files;
+
+import org.objectweb.asm.AnnotationVisitor;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.objectweb.asm.Opcodes.ASM4;
+
+/**
+ * Finds and deletes typedef annotation classes (and also warns if their
+ * retention was wrong, such that uses embeds
+ */
+public class RmTypeDefs {
+
+    private static final String ANNOTATION = "java/lang/annotation/Annotation";
+    private static final String STRING_DEF = "android/annotation/StringDef";
+    private static final String INT_DEF = "android/annotation/IntDef";
+    private static final String INT_DEF_DESC = "L" + INT_DEF + ";";
+    private static final String STRING_DEF_DESC = "L" + STRING_DEF + ";";
+    private static final String RETENTION_DESC = "Ljava/lang/annotation/Retention;";
+    private static final String RETENTION_POLICY_DESC = "Ljava/lang/annotation/RetentionPolicy;";
+    private static final String SOURCE_RETENTION_VALUE = "SOURCE";
+
+    private boolean mQuiet;
+    private boolean mVerbose;
+    private boolean mHaveError;
+    private boolean mDryRun;
+
+    public static void main(String[] args) {
+        new RmTypeDefs().run(args);
+    }
+
+    private void run(String[] args) {
+        if (args.length == 0) {
+            usage(System.err);
+            System.exit(1);
+        }
+
+        List<File> dirs = new ArrayList<File>();
+        for (String arg : args) {
+            if (arg.equals("--help") || arg.equals("-h")) {
+                usage(System.out);
+                return;
+            } else if (arg.equals("-q") || arg.equals("--quiet") || arg.equals("--silent")) {
+                mQuiet = true;
+            } else if (arg.equals("-v") || arg.equals("--verbose")) {
+                mVerbose = true;
+            } else if (arg.equals("-n") || arg.equals("--dry-run")) {
+                mDryRun = true;
+            } else if (arg.startsWith("-")) {
+                System.err.println("Unknown argument " + arg);
+                usage(System.err);
+                System.exit(1);
+
+            } else {
+                // Other arguments should be file names
+                File file = new File(arg);
+                if (file.exists()) {
+                    dirs.add(file);
+                } else {
+                    System.err.println(file + " does not exist");
+                    usage(System.err);
+                    System.exit(1);
+                }
+            }
+        }
+
+        if (!mQuiet) {
+            System.out.println("Deleting @IntDef and @StringDef annotation class files");
+        }
+
+        for (File dir : dirs) {
+            find(dir);
+        }
+
+        System.exit(mHaveError ? -1 : 0);
+    }
+
+    private void find(File file) {
+        if (file.isDirectory()) {
+            File[] files = file.listFiles();
+            if (files != null) {
+                for (File f : files) {
+                    find(f);
+                }
+            }
+        } else if (file.isFile()) {
+            String path = file.getPath();
+            if (path.endsWith(".class")) {
+                checkClass(file);
+            } else if (path.endsWith(".jar")) {
+                System.err.println(path + ": Warning: Encountered .jar file; .class files "
+                        + "are not scanned and removed inside .jar files");
+            }
+        }
+    }
+
+    private void checkClass(File file) {
+        try {
+            byte[] bytes = Files.toByteArray(file);
+            ClassReader classReader = new ClassReader(bytes);
+            classReader.accept(new MyVisitor(file), 0);
+        } catch (IOException e) {
+            System.err.println("Could not read " + file + ": " + e.getLocalizedMessage());
+            System.exit(1);
+        }
+    }
+
+    /**
+     * Prints usage statement.
+     */
+    static void usage(PrintStream out) {
+        out.println("Android TypeDef Remover 1.0");
+        out.println("Copyright (C) 2013 The Android Open Source Project\n");
+        out.println("Usage: rmtypedefs folder1 [folder2 [folder3...]]\n");
+        out.println("Options:");
+        out.println("  -h,--help                  show this message");
+        out.println("  -q,--quiet                 quiet");
+        out.println("  -v,--verbose               verbose");
+        out.println("  -n,--dry-run               dry-run only, leaves files alone");
+    }
+
+    private class MyVisitor extends ClassVisitor {
+
+        /** Class file name */
+        private File mFile;
+
+        /** Class name */
+        private String mName;
+
+        /** Is this class an annotation? */
+        private boolean mAnnotation;
+
+        /** Is this annotation a typedef? Only applies if {@link #mAnnotation} */
+        private boolean mTypedef;
+
+        /** Does the annotation have source retention? Only applies if {@link #mAnnotation} */
+        private boolean mSourceRetention;
+
+        public MyVisitor(File file) {
+            super(ASM4);
+            mFile = file;
+        }
+
+        public void visit(
+                int version,
+                int access,
+                String name,
+                String signature,
+                String superName,
+                String[] interfaces) {
+            mName = name;
+            mAnnotation = interfaces != null && interfaces.length >= 1
+                    && ANNOTATION.equals(interfaces[0]);
+
+            // Special case: Also delete the actual @IntDef and @StringDef .class files.
+            // These have class file retention
+            mTypedef = name.equals(INT_DEF) || name.equals(STRING_DEF);
+        }
+
+        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
+            mTypedef = desc.equals(INT_DEF_DESC) || desc.equals(STRING_DEF_DESC);
+            if (desc.equals(RETENTION_DESC)) {
+                return new AnnotationVisitor(ASM4) {
+                    public void visitEnum(String name, String desc, String value) {
+                        if (desc.equals(RETENTION_POLICY_DESC)) {
+                            mSourceRetention = SOURCE_RETENTION_VALUE.equals(value);
+                        }
+                    }
+                };
+            }
+            return null;
+        }
+
+        public void visitEnd() {
+            if (mAnnotation && mTypedef) {
+                if (!mSourceRetention && !mName.equals(STRING_DEF) && !mName.equals(INT_DEF)) {
+                    System.err.println(mFile + ": Warning: Annotation should be annotated "
+                            + "with @Retention(RetentionPolicy.SOURCE)");
+                    mHaveError = true;
+                }
+                if (mVerbose) {
+                    if (mDryRun) {
+                        System.out.println("Would delete " + mFile);
+                    } else {
+                        System.out.println("Deleting " + mFile);
+                    }
+                }
+                if (!mDryRun) {
+                    boolean deleted = mFile.delete();
+                    if (!deleted) {
+                        System.err.println("Could not delete " + mFile);
+                        mHaveError = true;
+                    }
+                }
+            }
+        }
+    }
+}
+
diff --git a/tutorials/MoarRam/README.txt b/tutorials/MoarRam/README.txt
index 028389b..8f1a487 100644
--- a/tutorials/MoarRam/README.txt
+++ b/tutorials/MoarRam/README.txt
@@ -12,3 +12,6 @@
 
 Each allocation can be freed by clicking the corresponding free button in the
 UI.
+
+NOTE 09/16/2013
+A new feature is added to force a double free. Both debug libc and Valgrind can capture it.
diff --git a/tutorials/MoarRam/jni/Android.mk b/tutorials/MoarRam/jni/Android.mk
index 933cbdf..b1eec37 100644
--- a/tutorials/MoarRam/jni/Android.mk
+++ b/tutorials/MoarRam/jni/Android.mk
@@ -41,3 +41,12 @@
 LOCAL_SHARED_LIBRARIES += liblog
 
 include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE    := libmoarram-doublefree
+LOCAL_SRC_FILES := df.c
+LOCAL_SHARED_LIBRARIES += liblog
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/tutorials/MoarRam/jni/df.c b/tutorials/MoarRam/jni/df.c
new file mode 100644
index 0000000..bfea6b8
--- /dev/null
+++ b/tutorials/MoarRam/jni/df.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2013 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.
+ *
+ */
+
+#include <jni.h>
+#include <cutils/log.h>
+
+#if defined(LOG_TAG)
+#undef LOG_TAG
+#define LOG_TAG "MOARRAM"
+#endif
+
+void
+Java_com_android_benchmark_moarram_MainActivity_forceDoubleFreeNative(
+    JNIEnv*  env,
+    jobject  this)
+{
+    char *ptr = (char *) malloc(4);
+    *ptr = 0;
+    ALOGW("About to double free %p", ptr);
+    free(ptr);
+    free(ptr);
+}
diff --git a/tutorials/MoarRam/res/layout/activity_main.xml b/tutorials/MoarRam/res/layout/activity_main.xml
index 8319bd7..50b6745 100644
--- a/tutorials/MoarRam/res/layout/activity_main.xml
+++ b/tutorials/MoarRam/res/layout/activity_main.xml
@@ -101,4 +101,19 @@
         android:layout_weight="1"
         android:onClick="freeVariableSizedBlocks" />
     </LinearLayout>
+
+    <LinearLayout
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:layout_weight="1"
+    android:orientation="horizontal">
+
+    <Button
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:text="@string/force_double_free"
+        android:layout_weight="1"
+        android:onClick="forceDoubleFree" />
+    </LinearLayout>
+
 </LinearLayout>
diff --git a/tutorials/MoarRam/res/values/strings.xml b/tutorials/MoarRam/res/values/strings.xml
index 0c0031d..e289fd8 100644
--- a/tutorials/MoarRam/res/values/strings.xml
+++ b/tutorials/MoarRam/res/values/strings.xml
@@ -13,4 +13,5 @@
     <string name="free_variable">Free 17 or 71 bytes</string>
     <string name="_17byte">17 bytes</string>
     <string name="_71byte">71 bytes</string>
+    <string name="force_double_free">Force a Double Free</string>
 </resources>
diff --git a/tutorials/MoarRam/src/com/android/benchmark/moarram/MainActivity.java b/tutorials/MoarRam/src/com/android/benchmark/moarram/MainActivity.java
index aa83b8c..0b7dcbc 100644
--- a/tutorials/MoarRam/src/com/android/benchmark/moarram/MainActivity.java
+++ b/tutorials/MoarRam/src/com/android/benchmark/moarram/MainActivity.java
@@ -14,6 +14,7 @@
         System.loadLibrary("moarram-32");
         System.loadLibrary("moarram-2M");
         System.loadLibrary("moarram-17_71");
+        System.loadLibrary("moarram-doublefree");
         setContentView(R.layout.activity_main);
     }
 
@@ -55,10 +56,15 @@
         freeVariableSizedBlocksNative(sizeId == R.id.radio17 ? 0 : 1);
     }
 
+    public void forceDoubleFree(View view) {
+        forceDoubleFreeNative();
+    }
+
     public native void add32ByteBlocksNative();
     public native void free32ByteBlocksNative();
     public native void add2MByteBlocksNative();
     public native void free2MByteBlocksNative();
     public native void addVariableSizedBlocksNative(int sizeId);
     public native void freeVariableSizedBlocksNative(int sizeId);
+    public native void forceDoubleFreeNative();
 }