Merge "Bug 5440088 Turn off the bugreport catpure by default."
diff --git a/apps/Fallback/res/values-af/strings.xml b/apps/Fallback/res/values-af/strings.xml
new file mode 100644
index 0000000..8cf16a7
--- /dev/null
+++ b/apps/Fallback/res/values-af/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Terugval"</string>
+    <string name="title" msgid="8156274565006125136">"Nie-ondersteunde handeling"</string>
+    <string name="error" msgid="6539615832923362301">"Hierdie handeling word tans nie ondersteun nie."</string>
+</resources>
diff --git a/apps/Fallback/res/values-am/strings.xml b/apps/Fallback/res/values-am/strings.xml
new file mode 100644
index 0000000..0c89122
--- /dev/null
+++ b/apps/Fallback/res/values-am/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Fallback"</string>
+    <string name="title" msgid="8156274565006125136">"የማይደገፍ ድርጊት"</string>
+    <string name="error" msgid="6539615832923362301">"ያድርጊት በአሁኑ ጊዜ የማይደገፍ ነው።"</string>
+</resources>
diff --git a/apps/Fallback/res/values-iw/strings.xml b/apps/Fallback/res/values-iw/strings.xml
index 671919b..cbf35ef 100644
--- a/apps/Fallback/res/values-iw/strings.xml
+++ b/apps/Fallback/res/values-iw/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="appTitle" msgid="161410001913116606">"חלופי"</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/strings.xml
new file mode 100644
index 0000000..930fe79
--- /dev/null
+++ b/apps/Fallback/res/values-ms/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Jatuh balik"</string>
+    <string name="title" msgid="8156274565006125136">"Tindakan tidak disokong"</string>
+    <string name="error" msgid="6539615832923362301">"Tindakan tidak disokong pada masa ini."</string>
+</resources>
diff --git a/apps/Fallback/res/values-sw/strings.xml b/apps/Fallback/res/values-sw/strings.xml
new file mode 100644
index 0000000..4b07acb
--- /dev/null
+++ b/apps/Fallback/res/values-sw/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Kimbilio"</string>
+    <string name="title" msgid="8156274565006125136">"Kitendo kisichohimiliwa"</string>
+    <string name="error" msgid="6539615832923362301">"Kitendo hakihimili kwa sasa."</string>
+</resources>
diff --git a/apps/Fallback/res/values-zu/strings.xml b/apps/Fallback/res/values-zu/strings.xml
new file mode 100644
index 0000000..2c85d28
--- /dev/null
+++ b/apps/Fallback/res/values-zu/strings.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  Copyright (C) 2007 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+ -->
+
+<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">"Buyela emuva"</string>
+    <string name="title" msgid="8156274565006125136">"Isenzo esingasekelwe"</string>
+    <string name="error" msgid="6539615832923362301">"Leso senzo okwamanje asisekelwe."</string>
+</resources>
diff --git a/build/sdk.atree b/build/sdk.atree
index ad1d19f..35ca61a 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -79,7 +79,8 @@
 development/tools/emulator/skins/WVGA800   platforms/${PLATFORM_NAME}/skins/WVGA800
 development/tools/emulator/skins/WVGA854   platforms/${PLATFORM_NAME}/skins/WVGA854
 development/tools/emulator/skins/WSVGA     platforms/${PLATFORM_NAME}/skins/WSVGA
-development/tools/emulator/skins/WXGA      platforms/${PLATFORM_NAME}/skins/WXGA
+development/tools/emulator/skins/WXGA720   platforms/${PLATFORM_NAME}/skins/WXGA720
+development/tools/emulator/skins/WXGA800   platforms/${PLATFORM_NAME}/skins/WXGA800
 
 # Platform SDK properties
 development/sdk/sdk.properties               platforms/${PLATFORM_NAME}/sdk.properties
@@ -152,6 +153,8 @@
 #
 development/samples/AccessibilityService       samples/${PLATFORM_NAME}/AccessibilityService
 development/samples/AccelerometerPlay          samples/${PLATFORM_NAME}/AccelerometerPlay
+development/samples/ActionBarCompat            samples/${PLATFORM_NAME}/ActionBarCompat
+development/samples/AndroidBeam                samples/${PLATFORM_NAME}/AndroidBeam
 development/samples/ApiDemos                   samples/${PLATFORM_NAME}/ApiDemos
 development/samples/BackupRestore              samples/${PLATFORM_NAME}/BackupRestore
 development/samples/BasicGLSurfaceView         samples/${PLATFORM_NAME}/BasicGLSurfaceView
@@ -165,7 +168,9 @@
 development/samples/LunarLander                samples/${PLATFORM_NAME}/LunarLander
 development/samples/MultiResolution            samples/${PLATFORM_NAME}/MultiResolution
 development/samples/NotePad                    samples/${PLATFORM_NAME}/NotePad
+development/samples/NFCDemo                    samples/${PLATFORM_NAME}/NFCDemo
 development/samples/RandomMusicPlayer          samples/${PLATFORM_NAME}/RandomMusicPlayer
+development/samples/SampleSpellCheckerService  samples/${PLATFORM_NAME}/SampleSpellCheckerService
 development/samples/SampleSyncAdapter          samples/${PLATFORM_NAME}/SampleSyncAdapter
 development/samples/SearchableDictionary       samples/${PLATFORM_NAME}/SearchableDictionary
 development/samples/SipDemo                    samples/${PLATFORM_NAME}/SipDemo
@@ -183,6 +188,7 @@
 development/samples/VoicemailProviderDemo      samples/${PLATFORM_NAME}/VoicemailProviderDemo
 development/samples/WeatherListWidget          samples/${PLATFORM_NAME}/WeatherListWidget
 development/apps/WidgetPreview                 samples/${PLATFORM_NAME}/WidgetPreview
+development/samples/WiFiDirectDemo             samples/${PLATFORM_NAME}/WiFiDirectDemo
 development/samples/Wiktionary                 samples/${PLATFORM_NAME}/Wiktionary
 development/samples/WiktionarySimple           samples/${PLATFORM_NAME}/WiktionarySimple
 development/samples/XmlAdapters                samples/${PLATFORM_NAME}/XmlAdapters
diff --git a/build/tools/mk_sdk_repo_xml.sh b/build/tools/mk_sdk_repo_xml.sh
index 496ee6c..a97ecaf 100755
--- a/build/tools/mk_sdk_repo_xml.sh
+++ b/build/tools/mk_sdk_repo_xml.sh
@@ -6,7 +6,7 @@
 
 PROG_DIR=$(dirname $0)
 
-TYPES="tool platform-tool platform sample doc add-on"
+TYPES="tool platform-tool platform sample doc add-on system-image source support"
 OSES="linux macosx windows any linux-x86 darwin"
 
 TMP_DIR=$(mktemp -d -t sdkrepo.tmp.XXXXXXXX)
@@ -151,11 +151,15 @@
 
 while [[ -n "$1" ]]; do
   # Process archives.
-  # First we expect a type. For conveniency the type can be plural.
+  # First we expect a type. For convenience the type can be plural.
   TYPE=$(check_enum "${1%%s}" $TYPES)
   [[ -z $TYPE ]] && error "Unknown archive type '$1'."
   shift
 
+  ELEMENT="$TYPE"
+  # The element name is different for extras:
+  [[ "$TYPE" == "support" ]] && ELEMENT="extra"
+
   MAP=""
   FIRST="1"
   LIBS_XML=""
@@ -230,7 +234,7 @@
       MAP=$(parse_attributes "$PROPS" ${ATTRS[@]})
 
       # Time to generate the XML for the package
-      echo "    <sdk:${TYPE}>" >> "$OUT"
+      echo "    <sdk:${ELEMENT}>" >> "$OUT"
       output_attributes "$OUT" $MAP
       [[ -n "$LIBS_XML" ]] && echo "$LIBS_XML" >> "$OUT"
       echo "        <sdk:archives>" >> "$OUT"
@@ -259,7 +263,7 @@
 
     if [[ ! "$OS" ]]; then
       echo "        </sdk:archives>" >> "$OUT"
-      echo "    </sdk:${TYPE}>" >> "$OUT"
+      echo "    </sdk:${ELEMENT}>" >> "$OUT"
     fi
   done
 
diff --git a/build/tools/mk_sources_zip.py b/build/tools/mk_sources_zip.py
new file mode 100755
index 0000000..3d4c582
--- /dev/null
+++ b/build/tools/mk_sources_zip.py
@@ -0,0 +1,202 @@
+#!/usr/bin/python
+#
+# 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.
+#
+
+import re
+import os
+import sys
+import getopt
+import zipfile
+
+VERBOSE = False
+TOP_FOLDER = "src"
+_RE_PKG = re.compile("^\s*package\s+([^\s;]+)\s*;.*")
+
+# Holds cmd-line arguments and context information
+class Params(object):
+    def __init__(self):
+        self.DRY = False
+        self.PROPS = None
+        self.SRC = None
+        self.DST = None
+        self.CNT_USED = 0
+        self.CNT_NOPKG = 0
+        # DIR is the list of directories to scan in TOPDIR.
+        self.DIR = "frameworks libcore"
+        # IGNORE is a list of namespaces to ignore. Must be java
+        # package definitions (e.g. "com.blah.foo.")
+        self.IGNORE = [ "sun.", "libcore.", "dalvik.",
+                        "com.test.", "com.google.",
+                        "coretestutils.", "test.", "test2.", "tests." ]
+        self.zipfile = None
+
+
+def verbose(msg, *args):
+    """Prints a verbose message to stderr if --verbose is set."""
+    global VERBOSE
+    if VERBOSE:
+        if args:
+            msg = msg % args
+        print >>sys.stderr, msg
+
+
+# Prints a usage summary
+def usage(error=None):
+    print """
+ Description:
+   This script collects all framework Java sources from the current android
+   source code and places them in a source.zip file that can be distributed
+   by the SDK Manager.
+
+ Usage:
+   %s [-n|-v] <source.properties> <sources.zip> <topdir>
+
+ The source.properties file must exist and will be injected in the Zip file.
+ The source directory must already exist.
+ Use -v for verbose output (lists each file being picked up or ignored).
+ Use -n for a dry-run (doesn't write the zip file).
+
+""" % sys.argv[0]
+
+    if error:
+        print >>sys.stderr, "Error:", error
+
+
+# Parse command line args, returns a Params instance or sys.exit(2) on error
+# after printing the error and the usage.
+def parseArgs(argv):
+    global VERBOSE
+    p = Params()
+    error = None
+
+    try:
+        opts, args = getopt.getopt(argv[1:],
+                                   "vns:",
+                                   [ "--verbose", "--dry", "--sourcedir=" ])
+    except getopt.GetoptError, e:
+        error = str(e)
+
+    if error is None:
+        for o, a in opts:
+            if o in [ "-n", "--dry" ]:
+                p.DRY = True
+            if o in [ "-v", "--verbose" ]:
+                VERBOSE = True
+            elif o in [ "-s", "--sourcedir" ]:
+                p.DIR = a
+
+        if len(args) != 3:
+            error = "Missing arguments: <source> <dest>"
+        else:
+            p.PROPS = args[0]
+            p.DST = args[1]
+            p.SRC = args[2]
+
+            if not os.path.isfile(p.PROPS):
+                error = "%s is not a file" % p.PROPS
+            if not os.path.isdir(p.SRC):
+                error = "%s is not a directory" % p.SRC
+
+    if error:
+        usage(error)
+        sys.exit(2)
+
+    return p
+
+
+# Recursively parses the given directory and processes java files found
+def parseSrcDir(p, srcdir):
+    if not os.path.exists(srcdir):
+        verbose("Error: Skipping unknown directory %s", srcdir)
+        return
+
+    for filename in os.listdir(srcdir):
+        filepath = os.path.join(srcdir, filename)
+        if filename.endswith(".java") and os.path.isfile(filepath):
+            pkg = checkJavaFile(filepath)
+            if not pkg:
+                verbose("No package found in %s", filepath)
+            if pkg:
+                # Should we ignore this package?
+                for ignore in p.IGNORE:
+                    if pkg.startswith(ignore):
+                        verbose("Ignore package %s [%s]", pkg, filepath)
+                        pkg = None
+                        break
+
+            if pkg:
+                pkg = pkg.replace(".", os.path.sep)  # e.g. android.view => android/view
+                copy(p, filepath, pkg)
+                p.CNT_USED += 1
+            else:
+                p.CNT_NOPKG += 1
+        elif os.path.isdir(filepath):
+            parseSrcDir(p, filepath)
+
+
+# Check a java file to find its package declaration, if any
+def checkJavaFile(path):
+    try:
+        f = None
+        try:
+            f = file(path)
+            for l in f.readlines():
+                m = _RE_PKG.match(l)
+                if m:
+                    return m.group(1)
+        finally:
+            if f: f.close()
+    except Exception:
+        pass
+
+    return None
+
+
+# Copy the given file (given its absolute filepath) to
+# the relative desk_pkg directory in the zip file.
+def copy(p, filepath, dest_pkg):
+    arc_path = os.path.join(TOP_FOLDER, dest_pkg, os.path.basename(filepath))
+    if p.DRY:
+        print >>sys.stderr, "zip %s [%s]" % (arc_path, filepath)
+    elif p.zipfile is not None:
+        p.zipfile.write(filepath, arc_path)
+
+
+def main():
+    p = parseArgs(sys.argv)
+    z = None
+    try:
+        if not p.DRY:
+            p.zipfile = z = zipfile.ZipFile(p.DST, "w", zipfile.ZIP_DEFLATED)
+            z.write(p.PROPS, TOP_FOLDER + "/source.properties")
+        for d in p.DIR.split():
+            if d:
+                parseSrcDir(p, os.path.join(p.SRC, d))
+    finally:
+        if z is not None:
+            z.close()
+    print "%s: %d java files copied" % (p.DST, p.CNT_USED)
+    if p.CNT_NOPKG:
+        print "%s: %d java files ignored" % (p.DST, p.CNT_NOPKG)
+    if p.DRY:
+        print >>sys.stderr, "This was in *DRY* mode. No copies done."
+
+
+if __name__ == "__main__":
+    main()
+
+# For emacs:
+# -*- tab-width: 4; -*-
diff --git a/build/tools/sdk_repo.mk b/build/tools/sdk_repo.mk
index c709502..de48e57 100644
--- a/build/tools/sdk_repo.mk
+++ b/build/tools/sdk_repo.mk
@@ -56,6 +56,48 @@
 	$(call sdk-repo-pkg-zip,$(1),$(2),$(3)):$(notdir $(call sdk-repo-pkg-zip,$(1),$(2),$(3)))
 endef
 
+# Defines the rule to build an SDK repository package when the
+# package directory contains 3 levels from the sdk dir, for example
+# to package SDK/extra/android/support or SDK/system-images/android-N/armeabi.
+# Because we do not know the intermediary directory name, this only works
+# if each directory contains a single sub-directory (e.g. sdk/$4/*/* must be
+# unique.)
+#
+# $1=OS (e.g. linux-x86, windows, etc)
+# $2=sdk zip (e.g. out/host/linux.../android-eng-sdk.zip)
+# $3=package to create (e.g. system-images, support, etc.)
+# $4=the root of directory to package in the sdk (e.g. extra/android).
+#    this must be a 2-segment path, the last one can be *.
+#
+# The rule depends on the SDK zip file, which is defined by $2.
+#
+define mk-sdk-repo-pkg-3
+$(call sdk-repo-pkg-zip,$(1),$(2),$(3)): $(2)
+	@echo "Building SDK repository package $(3) from $(notdir $(2))"
+	$(hide) cd $(basename $(2))/$(4) && \
+			zip -9rq ../../../$(notdir $(call sdk-repo-pkg-zip,$(1),$(2),$(3))) *
+$(call dist-for-goals, sdk_repo, $(call sdk-repo-pkg-zip,$(1),$(2),$(3)))
+SDK_REPO_XML_ARGS += $(3) $(1) \
+	$(call sdk-repo-pkg-zip,$(1),$(2),$(3)):$(notdir $(call sdk-repo-pkg-zip,$(1),$(2),$(3)))
+endef
+
+# Defines the rule to build an SDK sources package.
+#
+# $1=OS (e.g. linux-x86, windows, etc)
+# $2=sdk zip (e.g. out/host/linux.../android-eng-sdk.zip)
+# $3=package to create, must be "sources"
+#
+define mk-sdk-repo-sources
+$(call sdk-repo-pkg-zip,$(1),$(2),$(3)): $(2) $(TOPDIR)development/sdk/source_source.properties
+	@echo "Building SDK sources package"
+	$(hide) $(TOPDIR)development/build/tools/mk_sources_zip.py \
+			$(TOPDIR)development/sdk/source_source.properties \
+			$(call sdk-repo-pkg-zip,$(1),$(2),$(3)) \
+			$(TOPDIR).
+$(call dist-for-goals, sdk_repo, $(call sdk-repo-pkg-zip,$(1),$(2),$(3)))
+SDK_REPO_XML_ARGS += $(3) $(1) \
+	$(call sdk-repo-pkg-zip,$(1),$(2),$(3)):$(notdir $(call sdk-repo-pkg-zip,$(1),$(2),$(3)))
+endef
 
 # -----------------------------------------------------------------
 # Rules for win_sdk
@@ -67,7 +109,7 @@
 $(eval $(call mk-sdk-repo-pkg-1,windows,$(WIN_SDK_ZIP),platform-tools))
 
 SDK_REPO_DEPS += \
-		$(call sdk-repo-pkg-zip,windows,$(WIN_SDK_ZIP),tools) \
+	$(call sdk-repo-pkg-zip,windows,$(WIN_SDK_ZIP),tools) \
         $(call sdk-repo-pkg-zip,windows,$(WIN_SDK_ZIP),platform-tools)
 
 endif
@@ -82,6 +124,9 @@
 $(eval $(call mk-sdk-repo-pkg-1,$(HOST_OS),$(MAIN_SDK_ZIP),docs))
 $(eval $(call mk-sdk-repo-pkg-2,$(HOST_OS),$(MAIN_SDK_ZIP),platforms))
 $(eval $(call mk-sdk-repo-pkg-2,$(HOST_OS),$(MAIN_SDK_ZIP),samples))
+$(eval $(call mk-sdk-repo-pkg-3,$(HOST_OS),$(MAIN_SDK_ZIP),system-images,system-images/*))
+$(eval $(call mk-sdk-repo-pkg-3,$(HOST_OS),$(MAIN_SDK_ZIP),support,extras/android))
+$(eval $(call mk-sdk-repo-sources,$(HOST_OS),$(MAIN_SDK_ZIP),sources))
 
 SDK_REPO_DEPS += \
 		$(call sdk-repo-pkg-zip,$(HOST_OS),$(MAIN_SDK_ZIP),tools) \
@@ -89,6 +134,9 @@
 		$(call sdk-repo-pkg-zip,$(HOST_OS),$(MAIN_SDK_ZIP),docs) \
 		$(call sdk-repo-pkg-zip,$(HOST_OS),$(MAIN_SDK_ZIP),platforms) \
 		$(call sdk-repo-pkg-zip,$(HOST_OS),$(MAIN_SDK_ZIP),samples) \
+		$(call sdk-repo-pkg-zip,$(HOST_OS),$(MAIN_SDK_ZIP),system-images) \
+		$(call sdk-repo-pkg-zip,$(HOST_OS),$(MAIN_SDK_ZIP),support) \
+		$(call sdk-repo-pkg-zip,$(HOST_OS),$(MAIN_SDK_ZIP),sources)
 
 endif
 
diff --git a/data/etc/apns-conf.xml b/data/etc/apns-conf.xml
index 156fec2..2fe90d9 100644
--- a/data/etc/apns-conf.xml
+++ b/data/etc/apns-conf.xml
@@ -19,7 +19,7 @@
 
 <!-- use empty string to specify no proxy or port -->
 <!-- This version must agree with that in apps/common/res/apns.xml -->
-<apns version="6">
+<apns version="7">
     <apn carrier="T-Mobile US"
          mcc="310"
          mnc="260"
diff --git a/data/etc/apns-conf_sdk.xml b/data/etc/apns-conf_sdk.xml
index 5129dc7..0e9cf7d 100644
--- a/data/etc/apns-conf_sdk.xml
+++ b/data/etc/apns-conf_sdk.xml
@@ -23,7 +23,7 @@
 
 <!-- use empty string to specify no proxy or port -->
 <!-- This version must agree with that in apps/common/res/apns.xml -->
-<apns version="6">
+<apns version="7">
     <apn carrier="Android"
         mcc="310"
         mnc="995"
diff --git a/ndk/platforms/android-11/arch-arm/lib/libandroid.so b/ndk/platforms/android-11/arch-arm/lib/libandroid.so
deleted file mode 100755
index 3dce838..0000000
--- a/ndk/platforms/android-11/arch-arm/lib/libandroid.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-11/arch-arm/symbols/libandroid.so.txt b/ndk/platforms/android-11/arch-arm/symbols/libandroid.so.txt
deleted file mode 100644
index 5baa7c6..0000000
--- a/ndk/platforms/android-11/arch-arm/symbols/libandroid.so.txt
+++ /dev/null
@@ -1,153 +0,0 @@
-AAssetDir_close
-AAssetDir_getNextFileName
-AAssetDir_rewind
-AAssetManager_fromJava
-AAssetManager_open
-AAssetManager_openDir
-AAsset_close
-AAsset_getBuffer
-AAsset_getLength
-AAsset_getLength64
-AAsset_getRemainingLength
-AAsset_getRemainingLength64
-AAsset_isAllocated
-AAsset_openFileDescriptor
-AAsset_openFileDescriptor64
-AAsset_read
-AAsset_seek
-AAsset_seek64
-AConfiguration_copy
-AConfiguration_delete
-AConfiguration_diff
-AConfiguration_fromAssetManager
-AConfiguration_getCountry
-AConfiguration_getDensity
-AConfiguration_getKeyboard
-AConfiguration_getKeysHidden
-AConfiguration_getLanguage
-AConfiguration_getMcc
-AConfiguration_getMnc
-AConfiguration_getNavHidden
-AConfiguration_getNavigation
-AConfiguration_getOrientation
-AConfiguration_getScreenLong
-AConfiguration_getScreenSize
-AConfiguration_getSdkVersion
-AConfiguration_getTouchscreen
-AConfiguration_getUiModeNight
-AConfiguration_getUiModeType
-AConfiguration_isBetterThan
-AConfiguration_match
-AConfiguration_new
-AConfiguration_setCountry
-AConfiguration_setDensity
-AConfiguration_setKeyboard
-AConfiguration_setKeysHidden
-AConfiguration_setLanguage
-AConfiguration_setMcc
-AConfiguration_setMnc
-AConfiguration_setNavHidden
-AConfiguration_setNavigation
-AConfiguration_setOrientation
-AConfiguration_setScreenLong
-AConfiguration_setScreenSize
-AConfiguration_setSdkVersion
-AConfiguration_setTouchscreen
-AConfiguration_setUiModeNight
-AConfiguration_setUiModeType
-AInputEvent_getDeviceId
-AInputEvent_getSource
-AInputEvent_getType
-AInputQueue_attachLooper
-AInputQueue_detachLooper
-AInputQueue_finishEvent
-AInputQueue_getEvent
-AInputQueue_hasEvents
-AInputQueue_preDispatchEvent
-AKeyEvent_getAction
-AKeyEvent_getDownTime
-AKeyEvent_getEventTime
-AKeyEvent_getFlags
-AKeyEvent_getKeyCode
-AKeyEvent_getMetaState
-AKeyEvent_getRepeatCount
-AKeyEvent_getScanCode
-ALooper_acquire
-ALooper_addFd
-ALooper_forThread
-ALooper_pollAll
-ALooper_pollOnce
-ALooper_prepare
-ALooper_release
-ALooper_removeFd
-ALooper_wake
-AMotionEvent_getAction
-AMotionEvent_getDownTime
-AMotionEvent_getEdgeFlags
-AMotionEvent_getEventTime
-AMotionEvent_getFlags
-AMotionEvent_getHistoricalEventTime
-AMotionEvent_getHistoricalPressure
-AMotionEvent_getHistoricalSize
-AMotionEvent_getHistoricalX
-AMotionEvent_getHistoricalY
-AMotionEvent_getHistorySize
-AMotionEvent_getMetaState
-AMotionEvent_getOrientation
-AMotionEvent_getPointerCount
-AMotionEvent_getPointerId
-AMotionEvent_getPressure
-AMotionEvent_getRawX
-AMotionEvent_getRawY
-AMotionEvent_getSize
-AMotionEvent_getToolMajor
-AMotionEvent_getToolMinor
-AMotionEvent_getTouchMajor
-AMotionEvent_getTouchMinor
-AMotionEvent_getX
-AMotionEvent_getXOffset
-AMotionEvent_getXPrecision
-AMotionEvent_getY
-AMotionEvent_getYOffset
-AMotionEvent_getYPrecision
-ANativeActivity_finish
-ANativeActivity_hideSoftInput
-ANativeActivity_setWindowFlags
-ANativeActivity_setWindowFormat
-ANativeActivity_showSoftInput
-ANativeWindow_acquire
-ANativeWindow_fromSurface
-ANativeWindow_getFormat
-ANativeWindow_getHeight
-ANativeWindow_getWidth
-ANativeWindow_lock
-ANativeWindow_release
-ANativeWindow_setBuffersGeometry
-ANativeWindow_unlockAndPost
-AObbInfo_delete
-AObbInfo_getFlags
-AObbInfo_getPackageName
-AObbInfo_getVersion
-AObbScanner_getObbInfo
-ASensorEventQueue_disableSensor
-ASensorEventQueue_enableSensor
-ASensorEventQueue_getEvents
-ASensorEventQueue_hasEvents
-ASensorEventQueue_setEventRate
-ASensorManager_createEventQueue
-ASensorManager_destroyEventQueue
-ASensorManager_getDefaultSensor
-ASensorManager_getInstance
-ASensorManager_getSensorList
-ASensor_getMinDelay
-ASensor_getName
-ASensor_getResolution
-ASensor_getType
-ASensor_getVendor
-AStorageManager_delete
-AStorageManager_getMountedObbPath
-AStorageManager_isObbMounted
-AStorageManager_mountObb
-AStorageManager_new
-AStorageManager_unmountObb
-
diff --git a/ndk/platforms/android-11/include/android/asset_manager.h b/ndk/platforms/android-11/include/android/asset_manager.h
deleted file mode 100644
index f5df46b..0000000
--- a/ndk/platforms/android-11/include/android/asset_manager.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_ASSET_MANAGER_H
-#define ANDROID_ASSET_MANAGER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct AAssetManager;
-typedef struct AAssetManager AAssetManager;
-
-struct AAssetDir;
-typedef struct AAssetDir AAssetDir;
-
-struct AAsset;
-typedef struct AAsset AAsset;
-
-/* Available modes for opening assets */
-enum {
-    AASSET_MODE_UNKNOWN      = 0,
-    AASSET_MODE_RANDOM       = 1,
-    AASSET_MODE_STREAMING    = 2,
-    AASSET_MODE_BUFFER       = 3
-};
-
-
-/**
- * Open the named directory within the asset hierarchy.  The directory can then
- * be inspected with the AAssetDir functions.  To open the top-level directory,
- * pass in "" as the dirName.
- *
- * The object returned here should be freed by calling AAssetDir_close().
- */
-AAssetDir* AAssetManager_openDir(AAssetManager* mgr, const char* dirName);
-
-/**
- * Open an asset.
- *
- * The object returned here should be freed by calling AAsset_close().
- */
-AAsset* AAssetManager_open(AAssetManager* mgr, const char* filename, int mode);
-
-/**
- * Iterate over the files in an asset directory.  A NULL string is returned
- * when all the file names have been returned.
- *
- * The returned file name is suitable for passing to AAssetManager_open().
- *
- * The string returned here is owned by the AssetDir implementation and is not
- * guaranteed to remain valid if any other calls are made on this AAssetDir
- * instance.
- */
-const char* AAssetDir_getNextFileName(AAssetDir* assetDir);
-
-/**
- * Reset the iteration state of AAssetDir_getNextFileName() to the beginning.
- */
-void AAssetDir_rewind(AAssetDir* assetDir);
-
-/**
- * Close an opened AAssetDir, freeing any related resources.
- */
-void AAssetDir_close(AAssetDir* assetDir);
-
-/**
- * Attempt to read 'count' bytes of data from the current offset.
- *
- * Returns the number of bytes read, zero on EOF, or < 0 on error.
- */
-int AAsset_read(AAsset* asset, void* buf, size_t count);
-
-/**
- * Seek to the specified offset within the asset data.  'whence' uses the
- * same constants as lseek()/fseek().
- *
- * Returns the new position on success, or (off_t) -1 on error.
- */
-off_t AAsset_seek(AAsset* asset, off_t offset, int whence);
-
-/**
- * Seek to the specified offset within the asset data.  'whence' uses the
- * same constants as lseek()/fseek().
- *
- * Uses 64-bit data type for large files as opposed to the 32-bit type used
- * by AAsset_seek.
- *
- * Returns the new position on success, or (off64_t) -1 on error.
- */
-off64_t AAsset_seek64(AAsset* asset, off64_t offset, int whence);
-
-/**
- * Close the asset, freeing all associated resources.
- */
-void AAsset_close(AAsset* asset);
-
-/**
- * Get a pointer to a buffer holding the entire contents of the assset.
- *
- * Returns NULL on failure.
- */
-const void* AAsset_getBuffer(AAsset* asset);
-
-/**
- * Report the total size of the asset data.
- */
-off_t AAsset_getLength(AAsset* asset);
-
-/**
- * Report the total size of the asset data. Reports the size using a 64-bit
- * number insted of 32-bit as AAsset_getLength.
- */
-off64_t AAsset_getLength64(AAsset* asset);
-
-/**
- * Report the total amount of asset data that can be read from the current position.
- */
-off_t AAsset_getRemainingLength(AAsset* asset);
-
-/**
- * Report the total amount of asset data that can be read from the current position.
- *
- * Uses a 64-bit number instead of a 32-bit number as AAsset_getRemainingLength does.
- */
-off64_t AAsset_getRemainingLength64(AAsset* asset);
-
-/**
- * Open a new file descriptor that can be used to read the asset data. If the
- * start or length cannot be represented by a 32-bit number, it will be
- * truncated. If the file is large, use AAsset_openFileDescriptor64 instead.
- *
- * Returns < 0 if direct fd access is not possible (for example, if the asset is
- * compressed).
- */
-int AAsset_openFileDescriptor(AAsset* asset, off_t* outStart, off_t* outLength);
-
-/**
- * Open a new file descriptor that can be used to read the asset data.
- *
- * Uses a 64-bit number for the offset and length instead of 32-bit instead of
- * as AAsset_openFileDescriptor does.
- *
- * Returns < 0 if direct fd access is not possible (for example, if the asset is
- * compressed).
- */
-int AAsset_openFileDescriptor64(AAsset* asset, off64_t* outStart, off64_t* outLength);
-
-/**
- * Returns whether this asset's internal buffer is allocated in ordinary RAM (i.e. not
- * mmapped).
- */
-int AAsset_isAllocated(AAsset* asset);
-
-
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif      // ANDROID_ASSET_MANAGER_H
diff --git a/ndk/platforms/android-11/include/android/input.h b/ndk/platforms/android-11/include/android/input.h
deleted file mode 100644
index e196686..0000000
--- a/ndk/platforms/android-11/include/android/input.h
+++ /dev/null
@@ -1,724 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_INPUT_H
-#define _ANDROID_INPUT_H
-
-/******************************************************************
- *
- * IMPORTANT NOTICE:
- *
- *   This file is part of Android's set of stable system headers
- *   exposed by the Android NDK (Native Development Kit).
- *
- *   Third-party source AND binary code relies on the definitions
- *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
- *
- *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
- *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
- *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
- *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
- */
-
-/*
- * Structures and functions to receive and process input events in
- * native code.
- *
- * NOTE: These functions MUST be implemented by /system/lib/libui.so
- */
-
-#include <stdint.h>
-#include <sys/types.h>
-#include <android/keycodes.h>
-#include <android/looper.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Key states (may be returned by queries about the current state of a
- * particular key code, scan code or switch).
- */
-enum {
-    /* The key state is unknown or the requested key itself is not supported. */
-    AKEY_STATE_UNKNOWN = -1,
-
-    /* The key is up. */
-    AKEY_STATE_UP = 0,
-
-    /* The key is down. */
-    AKEY_STATE_DOWN = 1,
-
-    /* The key is down but is a virtual key press that is being emulated by the system. */
-    AKEY_STATE_VIRTUAL = 2
-};
-
-/*
- * Meta key / modifer state.
- */
-enum {
-    /* No meta keys are pressed. */
-    AMETA_NONE = 0,
-
-    /* This mask is used to check whether one of the ALT meta keys is pressed. */
-    AMETA_ALT_ON = 0x02,
-
-    /* This mask is used to check whether the left ALT meta key is pressed. */
-    AMETA_ALT_LEFT_ON = 0x10,
-
-    /* This mask is used to check whether the right ALT meta key is pressed. */
-    AMETA_ALT_RIGHT_ON = 0x20,
-
-    /* This mask is used to check whether one of the SHIFT meta keys is pressed. */
-    AMETA_SHIFT_ON = 0x01,
-
-    /* This mask is used to check whether the left SHIFT meta key is pressed. */
-    AMETA_SHIFT_LEFT_ON = 0x40,
-
-    /* This mask is used to check whether the right SHIFT meta key is pressed. */
-    AMETA_SHIFT_RIGHT_ON = 0x80,
-
-    /* This mask is used to check whether the SYM meta key is pressed. */
-    AMETA_SYM_ON = 0x04,
-
-    /* This mask is used to check whether the FUNCTION meta key is pressed. */
-    AMETA_FUNCTION_ON = 0x08,
-
-    /* This mask is used to check whether one of the CTRL meta keys is pressed. */
-    AMETA_CTRL_ON = 0x1000,
-
-    /* This mask is used to check whether the left CTRL meta key is pressed. */
-    AMETA_CTRL_LEFT_ON = 0x2000,
-
-    /* This mask is used to check whether the right CTRL meta key is pressed. */
-    AMETA_CTRL_RIGHT_ON = 0x4000,
-
-    /* This mask is used to check whether one of the META meta keys is pressed. */
-    AMETA_META_ON = 0x10000,
-
-    /* This mask is used to check whether the left META meta key is pressed. */
-    AMETA_META_LEFT_ON = 0x20000,
-
-    /* This mask is used to check whether the right META meta key is pressed. */
-    AMETA_META_RIGHT_ON = 0x40000,
-
-    /* This mask is used to check whether the CAPS LOCK meta key is on. */
-    AMETA_CAPS_LOCK_ON = 0x100000,
-
-    /* This mask is used to check whether the NUM LOCK meta key is on. */
-    AMETA_NUM_LOCK_ON = 0x200000,
-
-    /* This mask is used to check whether the SCROLL LOCK meta key is on. */
-    AMETA_SCROLL_LOCK_ON = 0x400000,
-};
-
-/*
- * Input events.
- *
- * Input events are opaque structures.  Use the provided accessors functions to
- * read their properties.
- */
-struct AInputEvent;
-typedef struct AInputEvent AInputEvent;
-
-/*
- * Input event types.
- */
-enum {
-    /* Indicates that the input event is a key event. */
-    AINPUT_EVENT_TYPE_KEY = 1,
-
-    /* Indicates that the input event is a motion event. */
-    AINPUT_EVENT_TYPE_MOTION = 2
-};
-
-/*
- * Key event actions.
- */
-enum {
-    /* The key has been pressed down. */
-    AKEY_EVENT_ACTION_DOWN = 0,
-
-    /* The key has been released. */
-    AKEY_EVENT_ACTION_UP = 1,
-
-    /* Multiple duplicate key events have occurred in a row, or a complex string is
-     * being delivered.  The repeat_count property of the key event contains the number
-     * of times the given key code should be executed.
-     */
-    AKEY_EVENT_ACTION_MULTIPLE = 2
-};
-
-/*
- * Key event flags.
- */
-enum {
-    /* This mask is set if the device woke because of this key event. */
-    AKEY_EVENT_FLAG_WOKE_HERE = 0x1,
-
-    /* This mask is set if the key event was generated by a software keyboard. */
-    AKEY_EVENT_FLAG_SOFT_KEYBOARD = 0x2,
-
-    /* This mask is set if we don't want the key event to cause us to leave touch mode. */
-    AKEY_EVENT_FLAG_KEEP_TOUCH_MODE = 0x4,
-
-    /* This mask is set if an event was known to come from a trusted part
-     * of the system.  That is, the event is known to come from the user,
-     * and could not have been spoofed by a third party component. */
-    AKEY_EVENT_FLAG_FROM_SYSTEM = 0x8,
-
-    /* This mask is used for compatibility, to identify enter keys that are
-     * coming from an IME whose enter key has been auto-labelled "next" or
-     * "done".  This allows TextView to dispatch these as normal enter keys
-     * for old applications, but still do the appropriate action when
-     * receiving them. */
-    AKEY_EVENT_FLAG_EDITOR_ACTION = 0x10,
-
-    /* When associated with up key events, this indicates that the key press
-     * has been canceled.  Typically this is used with virtual touch screen
-     * keys, where the user can slide from the virtual key area on to the
-     * display: in that case, the application will receive a canceled up
-     * event and should not perform the action normally associated with the
-     * key.  Note that for this to work, the application can not perform an
-     * action for a key until it receives an up or the long press timeout has
-     * expired. */
-    AKEY_EVENT_FLAG_CANCELED = 0x20,
-
-    /* This key event was generated by a virtual (on-screen) hard key area.
-     * Typically this is an area of the touchscreen, outside of the regular
-     * display, dedicated to "hardware" buttons. */
-    AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY = 0x40,
-
-    /* This flag is set for the first key repeat that occurs after the
-     * long press timeout. */
-    AKEY_EVENT_FLAG_LONG_PRESS = 0x80,
-
-    /* Set when a key event has AKEY_EVENT_FLAG_CANCELED set because a long
-     * press action was executed while it was down. */
-    AKEY_EVENT_FLAG_CANCELED_LONG_PRESS = 0x100,
-
-    /* Set for AKEY_EVENT_ACTION_UP when this event's key code is still being
-     * tracked from its initial down.  That is, somebody requested that tracking
-     * started on the key down and a long press has not caused
-     * the tracking to be canceled. */
-    AKEY_EVENT_FLAG_TRACKING = 0x200,
-
-    /* Set when a key event has been synthesized to implement default behavior
-     * for an event that the application did not handle.
-     * Fallback key events are generated by unhandled trackball motions
-     * (to emulate a directional keypad) and by certain unhandled key presses
-     * that are declared in the key map (such as special function numeric keypad
-     * keys when numlock is off). */
-    AKEY_EVENT_FLAG_FALLBACK = 0x400,
-};
-
-/*
- * Motion event actions.
- */
-
-/* Bit shift for the action bits holding the pointer index as
- * defined by AMOTION_EVENT_ACTION_POINTER_INDEX_MASK.
- */
-#define AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT 8
-
-enum {
-    /* Bit mask of the parts of the action code that are the action itself.
-     */
-    AMOTION_EVENT_ACTION_MASK = 0xff,
-
-    /* Bits in the action code that represent a pointer index, used with
-     * AMOTION_EVENT_ACTION_POINTER_DOWN and AMOTION_EVENT_ACTION_POINTER_UP.  Shifting
-     * down by AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT provides the actual pointer
-     * index where the data for the pointer going up or down can be found.
-     */
-    AMOTION_EVENT_ACTION_POINTER_INDEX_MASK  = 0xff00,
-
-    /* A pressed gesture has started, the motion contains the initial starting location.
-     */
-    AMOTION_EVENT_ACTION_DOWN = 0,
-
-    /* A pressed gesture has finished, the motion contains the final release location
-     * as well as any intermediate points since the last down or move event.
-     */
-    AMOTION_EVENT_ACTION_UP = 1,
-
-    /* A change has happened during a press gesture (between AMOTION_EVENT_ACTION_DOWN and
-     * AMOTION_EVENT_ACTION_UP).  The motion contains the most recent point, as well as
-     * any intermediate points since the last down or move event.
-     */
-    AMOTION_EVENT_ACTION_MOVE = 2,
-
-    /* The current gesture has been aborted.
-     * You will not receive any more points in it.  You should treat this as
-     * an up event, but not perform any action that you normally would.
-     */
-    AMOTION_EVENT_ACTION_CANCEL = 3,
-
-    /* A movement has happened outside of the normal bounds of the UI element.
-     * This does not provide a full gesture, but only the initial location of the movement/touch.
-     */
-    AMOTION_EVENT_ACTION_OUTSIDE = 4,
-
-    /* A non-primary pointer has gone down.
-     * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
-     */
-    AMOTION_EVENT_ACTION_POINTER_DOWN = 5,
-
-    /* A non-primary pointer has gone up.
-     * The bits in AMOTION_EVENT_ACTION_POINTER_INDEX_MASK indicate which pointer changed.
-     */
-    AMOTION_EVENT_ACTION_POINTER_UP = 6
-};
-
-/*
- * Motion event flags.
- */
-enum {
-    /* This flag indicates that the window that received this motion event is partly
-     * or wholly obscured by another visible window above it.  This flag is set to true
-     * even if the event did not directly pass through the obscured area.
-     * A security sensitive application can check this flag to identify situations in which
-     * a malicious application may have covered up part of its content for the purpose
-     * of misleading the user or hijacking touches.  An appropriate response might be
-     * to drop the suspect touches or to take additional precautions to confirm the user's
-     * actual intent.
-     */
-    AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED = 0x1,
-};
-
-/*
- * Motion event edge touch flags.
- */
-enum {
-    /* No edges intersected */
-    AMOTION_EVENT_EDGE_FLAG_NONE = 0,
-
-    /* Flag indicating the motion event intersected the top edge of the screen. */
-    AMOTION_EVENT_EDGE_FLAG_TOP = 0x01,
-
-    /* Flag indicating the motion event intersected the bottom edge of the screen. */
-    AMOTION_EVENT_EDGE_FLAG_BOTTOM = 0x02,
-
-    /* Flag indicating the motion event intersected the left edge of the screen. */
-    AMOTION_EVENT_EDGE_FLAG_LEFT = 0x04,
-
-    /* Flag indicating the motion event intersected the right edge of the screen. */
-    AMOTION_EVENT_EDGE_FLAG_RIGHT = 0x08
-};
-
-/*
- * Input sources.
- *
- * Refer to the documentation on android.view.InputDevice for more details about input sources
- * and their correct interpretation.
- */
-enum {
-    AINPUT_SOURCE_CLASS_MASK = 0x000000ff,
-
-    AINPUT_SOURCE_CLASS_BUTTON = 0x00000001,
-    AINPUT_SOURCE_CLASS_POINTER = 0x00000002,
-    AINPUT_SOURCE_CLASS_NAVIGATION = 0x00000004,
-    AINPUT_SOURCE_CLASS_POSITION = 0x00000008,
-};
-
-enum {
-    AINPUT_SOURCE_UNKNOWN = 0x00000000,
-
-    AINPUT_SOURCE_KEYBOARD = 0x00000100 | AINPUT_SOURCE_CLASS_BUTTON,
-    AINPUT_SOURCE_DPAD = 0x00000200 | AINPUT_SOURCE_CLASS_BUTTON,
-    AINPUT_SOURCE_TOUCHSCREEN = 0x00001000 | AINPUT_SOURCE_CLASS_POINTER,
-    AINPUT_SOURCE_MOUSE = 0x00002000 | AINPUT_SOURCE_CLASS_POINTER,
-    AINPUT_SOURCE_TRACKBALL = 0x00010000 | AINPUT_SOURCE_CLASS_NAVIGATION,
-    AINPUT_SOURCE_TOUCHPAD = 0x00100000 | AINPUT_SOURCE_CLASS_POSITION,
-
-    AINPUT_SOURCE_ANY = 0xffffff00,
-};
-
-/*
- * Keyboard types.
- *
- * Refer to the documentation on android.view.InputDevice for more details.
- */
-enum {
-    AINPUT_KEYBOARD_TYPE_NONE = 0,
-    AINPUT_KEYBOARD_TYPE_NON_ALPHABETIC = 1,
-    AINPUT_KEYBOARD_TYPE_ALPHABETIC = 2,
-};
-
-/*
- * Constants used to retrieve information about the range of motion for a particular
- * coordinate of a motion event.
- *
- * Refer to the documentation on android.view.InputDevice for more details about input sources
- * and their correct interpretation.
- */
-enum {
-    AINPUT_MOTION_RANGE_X = 0,
-    AINPUT_MOTION_RANGE_Y = 1,
-    AINPUT_MOTION_RANGE_PRESSURE = 2,
-    AINPUT_MOTION_RANGE_SIZE = 3,
-    AINPUT_MOTION_RANGE_TOUCH_MAJOR = 4,
-    AINPUT_MOTION_RANGE_TOUCH_MINOR = 5,
-    AINPUT_MOTION_RANGE_TOOL_MAJOR = 6,
-    AINPUT_MOTION_RANGE_TOOL_MINOR = 7,
-    AINPUT_MOTION_RANGE_ORIENTATION = 8,
-};
-
-
-/*
- * Input event accessors.
- *
- * Note that most functions can only be used on input events that are of a given type.
- * Calling these functions on input events of other types will yield undefined behavior.
- */
-
-/*** Accessors for all input events. ***/
-
-/* Get the input event type. */
-int32_t AInputEvent_getType(const AInputEvent* event);
-
-/* Get the id for the device that an input event came from.
- *
- * Input events can be generated by multiple different input devices.
- * Use the input device id to obtain information about the input
- * device that was responsible for generating a particular event.
- *
- * An input device id of 0 indicates that the event didn't come from a physical device;
- * other numbers are arbitrary and you shouldn't depend on the values.
- * Use the provided input device query API to obtain information about input devices.
- */
-int32_t AInputEvent_getDeviceId(const AInputEvent* event);
-
-/* Get the input event source. */
-int32_t AInputEvent_getSource(const AInputEvent* event);
-
-/*** Accessors for key events only. ***/
-
-/* Get the key event action. */
-int32_t AKeyEvent_getAction(const AInputEvent* key_event);
-
-/* Get the key event flags. */
-int32_t AKeyEvent_getFlags(const AInputEvent* key_event);
-
-/* Get the key code of the key event.
- * This is the physical key that was pressed, not the Unicode character. */
-int32_t AKeyEvent_getKeyCode(const AInputEvent* key_event);
-
-/* Get the hardware key id of this key event.
- * These values are not reliable and vary from device to device. */
-int32_t AKeyEvent_getScanCode(const AInputEvent* key_event);
-
-/* Get the meta key state. */
-int32_t AKeyEvent_getMetaState(const AInputEvent* key_event);
-
-/* Get the repeat count of the event.
- * For both key up an key down events, this is the number of times the key has
- * repeated with the first down starting at 0 and counting up from there.  For
- * multiple key events, this is the number of down/up pairs that have occurred. */
-int32_t AKeyEvent_getRepeatCount(const AInputEvent* key_event);
-
-/* Get the time of the most recent key down event, in the
- * java.lang.System.nanoTime() time base.  If this is a down event,
- * this will be the same as eventTime.
- * Note that when chording keys, this value is the down time of the most recently
- * pressed key, which may not be the same physical key of this event. */
-int64_t AKeyEvent_getDownTime(const AInputEvent* key_event);
-
-/* Get the time this event occurred, in the
- * java.lang.System.nanoTime() time base. */
-int64_t AKeyEvent_getEventTime(const AInputEvent* key_event);
-
-/*** Accessors for motion events only. ***/
-
-/* Get the combined motion event action code and pointer index. */
-int32_t AMotionEvent_getAction(const AInputEvent* motion_event);
-
-/* Get the motion event flags. */
-int32_t AMotionEvent_getFlags(const AInputEvent* motion_event);
-
-/* Get the state of any meta / modifier keys that were in effect when the
- * event was generated. */
-int32_t AMotionEvent_getMetaState(const AInputEvent* motion_event);
-
-/* Get a bitfield indicating which edges, if any, were touched by this motion event.
- * For touch events, clients can use this to determine if the user's finger was
- * touching the edge of the display. */
-int32_t AMotionEvent_getEdgeFlags(const AInputEvent* motion_event);
-
-/* Get the time when the user originally pressed down to start a stream of
- * position events, in the java.lang.System.nanoTime() time base. */
-int64_t AMotionEvent_getDownTime(const AInputEvent* motion_event);
-
-/* Get the time when this specific event was generated,
- * in the java.lang.System.nanoTime() time base. */
-int64_t AMotionEvent_getEventTime(const AInputEvent* motion_event);
-
-/* Get the X coordinate offset.
- * For touch events on the screen, this is the delta that was added to the raw
- * screen coordinates to adjust for the absolute position of the containing windows
- * and views. */
-float AMotionEvent_getXOffset(const AInputEvent* motion_event);
-
-/* Get the precision of the Y coordinates being reported.
- * For touch events on the screen, this is the delta that was added to the raw
- * screen coordinates to adjust for the absolute position of the containing windows
- * and views. */
-float AMotionEvent_getYOffset(const AInputEvent* motion_event);
-
-/* Get the precision of the X coordinates being reported.
- * You can multiply this number with an X coordinate sample to find the
- * actual hardware value of the X coordinate. */
-float AMotionEvent_getXPrecision(const AInputEvent* motion_event);
-
-/* Get the precision of the Y coordinates being reported.
- * You can multiply this number with a Y coordinate sample to find the
- * actual hardware value of the Y coordinate. */
-float AMotionEvent_getYPrecision(const AInputEvent* motion_event);
-
-/* Get the number of pointers of data contained in this event.
- * Always >= 1. */
-size_t AMotionEvent_getPointerCount(const AInputEvent* motion_event);
-
-/* Get the pointer identifier associated with a particular pointer
- * data index is this event.  The identifier tells you the actual pointer
- * number associated with the data, accounting for individual pointers
- * going up and down since the start of the current gesture. */
-int32_t AMotionEvent_getPointerId(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the original raw X coordinate of this event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views. */
-float AMotionEvent_getRawX(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the original raw X coordinate of this event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views. */
-float AMotionEvent_getRawY(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current X coordinate of this event for the given pointer index.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getX(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current Y coordinate of this event for the given pointer index.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getY(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current pressure of this event for the given pointer index.
- * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * however values higher than 1 may be generated depending on the calibration of
- * the input device. */
-float AMotionEvent_getPressure(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current scaled value of the approximate size for the given pointer index.
- * This represents some approximation of the area of the screen being
- * pressed; the actual value in pixels corresponding to the
- * touch is normalized with the device specific range of values
- * and scaled to a value between 0 and 1.  The value of size can be used to
- * determine fat touch events. */
-float AMotionEvent_getSize(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the major axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index. */
-float AMotionEvent_getTouchMajor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the minor axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index. */
-float AMotionEvent_getTouchMinor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the major axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getToolMajor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current length of the minor axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getToolMinor(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the current orientation of the touch area and tool area in radians clockwise from
- * vertical for the given pointer index.
- * An angle of 0 degrees indicates that the major axis of contact is oriented
- * upwards, is perfectly circular or is of unknown orientation.  A positive angle
- * indicates that the major axis of contact is oriented to the right.  A negative angle
- * indicates that the major axis of contact is oriented to the left.
- * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
- * (finger pointing fully right). */
-float AMotionEvent_getOrientation(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the number of historical points in this event.  These are movements that
- * have occurred between this event and the previous event.  This only applies
- * to AMOTION_EVENT_ACTION_MOVE events -- all other actions will have a size of 0.
- * Historical samples are indexed from oldest to newest. */
-size_t AMotionEvent_getHistorySize(const AInputEvent* motion_event);
-
-/* Get the time that a historical movement occurred between this event and
- * the previous event, in the java.lang.System.nanoTime() time base. */
-int64_t AMotionEvent_getHistoricalEventTime(AInputEvent* motion_event,
-        size_t history_index);
-
-/* Get the historical raw X coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalRawX(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the historical raw Y coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * For touch events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalRawY(const AInputEvent* motion_event, size_t pointer_index);
-
-/* Get the historical X coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalX(AInputEvent* motion_event, size_t pointer_index,
-        size_t history_index);
-
-/* Get the historical Y coordinate of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * Whole numbers are pixels; the value may have a fraction for input devices
- * that are sub-pixel precise. */
-float AMotionEvent_getHistoricalY(AInputEvent* motion_event, size_t pointer_index,
-        size_t history_index);
-
-/* Get the historical pressure of this event for the given pointer index that
- * occurred between this event and the previous motion event.
- * The pressure generally ranges from 0 (no pressure at all) to 1 (normal pressure),
- * however values higher than 1 may be generated depending on the calibration of
- * the input device. */
-float AMotionEvent_getHistoricalPressure(AInputEvent* motion_event, size_t pointer_index,
-        size_t history_index);
-
-/* Get the current scaled value of the approximate size for the given pointer index that
- * occurred between this event and the previous motion event.
- * This represents some approximation of the area of the screen being
- * pressed; the actual value in pixels corresponding to the
- * touch is normalized with the device specific range of values
- * and scaled to a value between 0 and 1.  The value of size can be used to
- * determine fat touch events. */
-float AMotionEvent_getHistoricalSize(AInputEvent* motion_event, size_t pointer_index,
-        size_t history_index);
-
-/* Get the historical length of the major axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index that
- * occurred between this event and the previous motion event. */
-float AMotionEvent_getHistoricalTouchMajor(const AInputEvent* motion_event, size_t pointer_index,
-        size_t history_index);
-
-/* Get the historical length of the minor axis of an ellipse that describes the touch area
- * at the point of contact for the given pointer index that
- * occurred between this event and the previous motion event. */
-float AMotionEvent_getHistoricalTouchMinor(const AInputEvent* motion_event, size_t pointer_index,
-        size_t history_index);
-
-/* Get the historical length of the major axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index that
- * occurred between this event and the previous motion event.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getHistoricalToolMajor(const AInputEvent* motion_event, size_t pointer_index,
-        size_t history_index);
-
-/* Get the historical length of the minor axis of an ellipse that describes the size
- * of the approaching tool for the given pointer index that
- * occurred between this event and the previous motion event.
- * The tool area represents the estimated size of the finger or pen that is
- * touching the device independent of its actual touch area at the point of contact. */
-float AMotionEvent_getHistoricalToolMinor(const AInputEvent* motion_event, size_t pointer_index,
-        size_t history_index);
-
-/* Get the historical orientation of the touch area and tool area in radians clockwise from
- * vertical for the given pointer index that
- * occurred between this event and the previous motion event.
- * An angle of 0 degrees indicates that the major axis of contact is oriented
- * upwards, is perfectly circular or is of unknown orientation.  A positive angle
- * indicates that the major axis of contact is oriented to the right.  A negative angle
- * indicates that the major axis of contact is oriented to the left.
- * The full range is from -PI/2 radians (finger pointing fully left) to PI/2 radians
- * (finger pointing fully right). */
-float AMotionEvent_getHistoricalOrientation(const AInputEvent* motion_event, size_t pointer_index,
-        size_t history_index);
-
-
-/*
- * Input queue
- *
- * An input queue is the facility through which you retrieve input
- * events.
- */
-struct AInputQueue;
-typedef struct AInputQueue AInputQueue;
-
-/*
- * Add this input queue to a looper for processing.  See
- * ALooper_addFd() for information on the ident, callback, and data params.
- */
-void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
-        int ident, ALooper_callbackFunc callback, void* data);
-
-/*
- * Remove the input queue from the looper it is currently attached to.
- */
-void AInputQueue_detachLooper(AInputQueue* queue);
-
-/*
- * Returns true if there are one or more events available in the
- * input queue.  Returns 1 if the queue has events; 0 if
- * it does not have events; and a negative value if there is an error.
- */
-int32_t AInputQueue_hasEvents(AInputQueue* queue);
-
-/*
- * Returns the next available event from the queue.  Returns a negative
- * value if no events are available or an error has occurred.
- */
-int32_t AInputQueue_getEvent(AInputQueue* queue, AInputEvent** outEvent);
-
-/*
- * Sends the key for standard pre-dispatching -- that is, possibly deliver
- * it to the current IME to be consumed before the app.  Returns 0 if it
- * was not pre-dispatched, meaning you can process it right now.  If non-zero
- * is returned, you must abandon the current event processing and allow the
- * event to appear again in the event queue (if it does not get consumed during
- * pre-dispatching).
- */
-int32_t AInputQueue_preDispatchEvent(AInputQueue* queue, AInputEvent* event);
-
-/*
- * Report that dispatching has finished with the given event.
- * This must be called after receiving an event with AInputQueue_get_event().
- */
-void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _ANDROID_INPUT_H
diff --git a/ndk/platforms/android-11/include/android/keycodes.h b/ndk/platforms/android-11/include/android/keycodes.h
deleted file mode 100644
index b026a0c..0000000
--- a/ndk/platforms/android-11/include/android/keycodes.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef _ANDROID_KEYCODES_H
-#define _ANDROID_KEYCODES_H
-
-/******************************************************************
- *
- * IMPORTANT NOTICE:
- *
- *   This file is part of Android's set of stable system headers
- *   exposed by the Android NDK (Native Development Kit).
- *
- *   Third-party source AND binary code relies on the definitions
- *   here to be FROZEN ON ALL UPCOMING PLATFORM RELEASES.
- *
- *   - DO NOT MODIFY ENUMS (EXCEPT IF YOU ADD NEW 32-BIT VALUES)
- *   - DO NOT MODIFY CONSTANTS OR FUNCTIONAL MACROS
- *   - DO NOT CHANGE THE SIGNATURE OF FUNCTIONS IN ANY WAY
- *   - DO NOT CHANGE THE LAYOUT OR SIZE OF STRUCTURES
- */
-
-#include <sys/types.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Key codes.
- */
-enum {
-    AKEYCODE_UNKNOWN         = 0,
-    AKEYCODE_SOFT_LEFT       = 1,
-    AKEYCODE_SOFT_RIGHT      = 2,
-    AKEYCODE_HOME            = 3,
-    AKEYCODE_BACK            = 4,
-    AKEYCODE_CALL            = 5,
-    AKEYCODE_ENDCALL         = 6,
-    AKEYCODE_0               = 7,
-    AKEYCODE_1               = 8,
-    AKEYCODE_2               = 9,
-    AKEYCODE_3               = 10,
-    AKEYCODE_4               = 11,
-    AKEYCODE_5               = 12,
-    AKEYCODE_6               = 13,
-    AKEYCODE_7               = 14,
-    AKEYCODE_8               = 15,
-    AKEYCODE_9               = 16,
-    AKEYCODE_STAR            = 17,
-    AKEYCODE_POUND           = 18,
-    AKEYCODE_DPAD_UP         = 19,
-    AKEYCODE_DPAD_DOWN       = 20,
-    AKEYCODE_DPAD_LEFT       = 21,
-    AKEYCODE_DPAD_RIGHT      = 22,
-    AKEYCODE_DPAD_CENTER     = 23,
-    AKEYCODE_VOLUME_UP       = 24,
-    AKEYCODE_VOLUME_DOWN     = 25,
-    AKEYCODE_POWER           = 26,
-    AKEYCODE_CAMERA          = 27,
-    AKEYCODE_CLEAR           = 28,
-    AKEYCODE_A               = 29,
-    AKEYCODE_B               = 30,
-    AKEYCODE_C               = 31,
-    AKEYCODE_D               = 32,
-    AKEYCODE_E               = 33,
-    AKEYCODE_F               = 34,
-    AKEYCODE_G               = 35,
-    AKEYCODE_H               = 36,
-    AKEYCODE_I               = 37,
-    AKEYCODE_J               = 38,
-    AKEYCODE_K               = 39,
-    AKEYCODE_L               = 40,
-    AKEYCODE_M               = 41,
-    AKEYCODE_N               = 42,
-    AKEYCODE_O               = 43,
-    AKEYCODE_P               = 44,
-    AKEYCODE_Q               = 45,
-    AKEYCODE_R               = 46,
-    AKEYCODE_S               = 47,
-    AKEYCODE_T               = 48,
-    AKEYCODE_U               = 49,
-    AKEYCODE_V               = 50,
-    AKEYCODE_W               = 51,
-    AKEYCODE_X               = 52,
-    AKEYCODE_Y               = 53,
-    AKEYCODE_Z               = 54,
-    AKEYCODE_COMMA           = 55,
-    AKEYCODE_PERIOD          = 56,
-    AKEYCODE_ALT_LEFT        = 57,
-    AKEYCODE_ALT_RIGHT       = 58,
-    AKEYCODE_SHIFT_LEFT      = 59,
-    AKEYCODE_SHIFT_RIGHT     = 60,
-    AKEYCODE_TAB             = 61,
-    AKEYCODE_SPACE           = 62,
-    AKEYCODE_SYM             = 63,
-    AKEYCODE_EXPLORER        = 64,
-    AKEYCODE_ENVELOPE        = 65,
-    AKEYCODE_ENTER           = 66,
-    AKEYCODE_DEL             = 67,
-    AKEYCODE_GRAVE           = 68,
-    AKEYCODE_MINUS           = 69,
-    AKEYCODE_EQUALS          = 70,
-    AKEYCODE_LEFT_BRACKET    = 71,
-    AKEYCODE_RIGHT_BRACKET   = 72,
-    AKEYCODE_BACKSLASH       = 73,
-    AKEYCODE_SEMICOLON       = 74,
-    AKEYCODE_APOSTROPHE      = 75,
-    AKEYCODE_SLASH           = 76,
-    AKEYCODE_AT              = 77,
-    AKEYCODE_NUM             = 78,
-    AKEYCODE_HEADSETHOOK     = 79,
-    AKEYCODE_FOCUS           = 80,   // *Camera* focus
-    AKEYCODE_PLUS            = 81,
-    AKEYCODE_MENU            = 82,
-    AKEYCODE_NOTIFICATION    = 83,
-    AKEYCODE_SEARCH          = 84,
-    AKEYCODE_MEDIA_PLAY_PAUSE= 85,
-    AKEYCODE_MEDIA_STOP      = 86,
-    AKEYCODE_MEDIA_NEXT      = 87,
-    AKEYCODE_MEDIA_PREVIOUS  = 88,
-    AKEYCODE_MEDIA_REWIND    = 89,
-    AKEYCODE_MEDIA_FAST_FORWARD = 90,
-    AKEYCODE_MUTE            = 91,
-    AKEYCODE_PAGE_UP         = 92,
-    AKEYCODE_PAGE_DOWN       = 93,
-    AKEYCODE_PICTSYMBOLS     = 94,
-    AKEYCODE_SWITCH_CHARSET  = 95,
-    AKEYCODE_BUTTON_A        = 96,
-    AKEYCODE_BUTTON_B        = 97,
-    AKEYCODE_BUTTON_C        = 98,
-    AKEYCODE_BUTTON_X        = 99,
-    AKEYCODE_BUTTON_Y        = 100,
-    AKEYCODE_BUTTON_Z        = 101,
-    AKEYCODE_BUTTON_L1       = 102,
-    AKEYCODE_BUTTON_R1       = 103,
-    AKEYCODE_BUTTON_L2       = 104,
-    AKEYCODE_BUTTON_R2       = 105,
-    AKEYCODE_BUTTON_THUMBL   = 106,
-    AKEYCODE_BUTTON_THUMBR   = 107,
-    AKEYCODE_BUTTON_START    = 108,
-    AKEYCODE_BUTTON_SELECT   = 109,
-    AKEYCODE_BUTTON_MODE     = 110,
-    AKEYCODE_ESCAPE          = 111,
-    AKEYCODE_FORWARD_DEL     = 112,
-    AKEYCODE_CTRL_LEFT       = 113,
-    AKEYCODE_CTRL_RIGHT      = 114,
-    AKEYCODE_CAPS_LOCK       = 115,
-    AKEYCODE_SCROLL_LOCK     = 116,
-    AKEYCODE_META_LEFT       = 117,
-    AKEYCODE_META_RIGHT      = 118,
-    AKEYCODE_FUNCTION        = 119,
-    AKEYCODE_SYSRQ           = 120,
-    AKEYCODE_BREAK           = 121,
-    AKEYCODE_MOVE_HOME       = 122,
-    AKEYCODE_MOVE_END        = 123,
-    AKEYCODE_INSERT          = 124,
-    AKEYCODE_FORWARD         = 125,
-    AKEYCODE_MEDIA_PLAY      = 126,
-    AKEYCODE_MEDIA_PAUSE     = 127,
-    AKEYCODE_MEDIA_CLOSE     = 128,
-    AKEYCODE_MEDIA_EJECT     = 129,
-    AKEYCODE_MEDIA_RECORD    = 130,
-    AKEYCODE_F1              = 131,
-    AKEYCODE_F2              = 132,
-    AKEYCODE_F3              = 133,
-    AKEYCODE_F4              = 134,
-    AKEYCODE_F5              = 135,
-    AKEYCODE_F6              = 136,
-    AKEYCODE_F7              = 137,
-    AKEYCODE_F8              = 138,
-    AKEYCODE_F9              = 139,
-    AKEYCODE_F10             = 140,
-    AKEYCODE_F11             = 141,
-    AKEYCODE_F12             = 142,
-    AKEYCODE_NUM_LOCK        = 143,
-    AKEYCODE_NUMPAD_0        = 144,
-    AKEYCODE_NUMPAD_1        = 145,
-    AKEYCODE_NUMPAD_2        = 146,
-    AKEYCODE_NUMPAD_3        = 147,
-    AKEYCODE_NUMPAD_4        = 148,
-    AKEYCODE_NUMPAD_5        = 149,
-    AKEYCODE_NUMPAD_6        = 150,
-    AKEYCODE_NUMPAD_7        = 151,
-    AKEYCODE_NUMPAD_8        = 152,
-    AKEYCODE_NUMPAD_9        = 153,
-    AKEYCODE_NUMPAD_DIVIDE   = 154,
-    AKEYCODE_NUMPAD_MULTIPLY = 155,
-    AKEYCODE_NUMPAD_SUBTRACT = 156,
-    AKEYCODE_NUMPAD_ADD      = 157,
-    AKEYCODE_NUMPAD_DOT      = 158,
-    AKEYCODE_NUMPAD_COMMA    = 159,
-    AKEYCODE_NUMPAD_ENTER    = 160,
-    AKEYCODE_NUMPAD_EQUALS   = 161,
-    AKEYCODE_NUMPAD_LEFT_PAREN = 162,
-    AKEYCODE_NUMPAD_RIGHT_PAREN = 163,
-    AKEYCODE_VOLUME_MUTE     = 164,
-    AKEYCODE_INFO            = 165,
-    AKEYCODE_CHANNEL_UP      = 166,
-    AKEYCODE_CHANNEL_DOWN    = 167,
-    AKEYCODE_ZOOM_IN         = 168,
-    AKEYCODE_ZOOM_OUT        = 169,
-    AKEYCODE_TV              = 170,
-    AKEYCODE_WINDOW          = 171,
-    AKEYCODE_GUIDE           = 172,
-    AKEYCODE_DVR             = 173,
-    AKEYCODE_BOOKMARK        = 174,
-    AKEYCODE_CAPTIONS        = 175,
-    AKEYCODE_SETTINGS        = 176,
-    AKEYCODE_TV_POWER        = 177,
-    AKEYCODE_TV_INPUT        = 178,
-    AKEYCODE_STB_POWER       = 179,
-    AKEYCODE_STB_INPUT       = 180,
-    AKEYCODE_AVR_POWER       = 181,
-    AKEYCODE_AVR_INPUT       = 182,
-    AKEYCODE_PROG_RED        = 183,
-    AKEYCODE_PROG_GREEN      = 184,
-    AKEYCODE_PROG_YELLOW     = 185,
-    AKEYCODE_PROG_BLUE       = 186,
-    AKEYCODE_APP_SWITCH      = 187,
-
-    // NOTE: If you add a new keycode here you must also add it to several other files.
-    //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.
-};
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // _ANDROID_KEYCODES_H
diff --git a/ndk/platforms/android-11/include/android/native_activity.h b/ndk/platforms/android-11/include/android/native_activity.h
deleted file mode 100644
index a361846..0000000
--- a/ndk/platforms/android-11/include/android/native_activity.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#ifndef ANDROID_NATIVE_ACTIVITY_H
-#define ANDROID_NATIVE_ACTIVITY_H
-
-#include <stdint.h>
-#include <sys/types.h>
-
-#include <jni.h>
-
-#include <android/asset_manager.h>
-#include <android/input.h>
-#include <android/native_window.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ANativeActivityCallbacks;
-
-/**
- * This structure defines the native side of an android.app.NativeActivity.
- * It is created by the framework, and handed to the application's native
- * code as it is being launched.
- */
-typedef struct ANativeActivity {
-    /**
-     * Pointer to the callback function table of the native application.
-     * You can set the functions here to your own callbacks.  The callbacks
-     * pointer itself here should not be changed; it is allocated and managed
-     * for you by the framework.
-     */
-    struct ANativeActivityCallbacks* callbacks;
-
-    /**
-     * The global handle on the process's Java VM.
-     */
-    JavaVM* vm;
-
-    /**
-     * JNI context for the main thread of the app.  Note that this field
-     * can ONLY be used from the main thread of the process; that is, the
-     * thread that calls into the ANativeActivityCallbacks.
-     */
-    JNIEnv* env;
-
-    /**
-     * The NativeActivity Java class.
-     */
-    jobject clazz;
-
-    /**
-     * Path to this application's internal data directory.
-     */
-    const char* internalDataPath;
-    
-    /**
-     * Path to this application's external (removable/mountable) data directory.
-     */
-    const char* externalDataPath;
-    
-    /**
-     * The platform's SDK version code.
-     */
-    int32_t sdkVersion;
-    
-    /**
-     * This is the native instance of the application.  It is not used by
-     * the framework, but can be set by the application to its own instance
-     * state.
-     */
-    void* instance;
-
-    /**
-     * Pointer to the Asset Manager instance for the application.  The application
-     * uses this to access binary assets bundled inside its own .apk file.
-     */
-    AAssetManager* assetManager;
-
-    /**
-     * Available starting with Honeycomb: path to the directory containing
-     * the application's OBB files (if any).  If the app doesn't have any
-     * OBB files, this directory may not exist.
-     */
-    const char* obbPath;
-} ANativeActivity;
-
-/**
- * These are the callbacks the framework makes into a native application.
- * All of these callbacks happen on the main thread of the application.
- * By default, all callbacks are NULL; set to a pointer to your own function
- * to have it called.
- */
-typedef struct ANativeActivityCallbacks {
-    /**
-     * NativeActivity has started.  See Java documentation for Activity.onStart()
-     * for more information.
-     */
-    void (*onStart)(ANativeActivity* activity);
-    
-    /**
-     * NativeActivity has resumed.  See Java documentation for Activity.onResume()
-     * for more information.
-     */
-    void (*onResume)(ANativeActivity* activity);
-    
-    /**
-     * Framework is asking NativeActivity to save its current instance state.
-     * See Java documentation for Activity.onSaveInstanceState() for more
-     * information.  The returned pointer needs to be created with malloc();
-     * the framework will call free() on it for you.  You also must fill in
-     * outSize with the number of bytes in the allocation.  Note that the
-     * saved state will be persisted, so it can not contain any active
-     * entities (pointers to memory, file descriptors, etc).
-     */
-    void* (*onSaveInstanceState)(ANativeActivity* activity, size_t* outSize);
-    
-    /**
-     * NativeActivity has paused.  See Java documentation for Activity.onPause()
-     * for more information.
-     */
-    void (*onPause)(ANativeActivity* activity);
-    
-    /**
-     * NativeActivity has stopped.  See Java documentation for Activity.onStop()
-     * for more information.
-     */
-    void (*onStop)(ANativeActivity* activity);
-    
-    /**
-     * NativeActivity is being destroyed.  See Java documentation for Activity.onDestroy()
-     * for more information.
-     */
-    void (*onDestroy)(ANativeActivity* activity);
-
-    /**
-     * Focus has changed in this NativeActivity's window.  This is often used,
-     * for example, to pause a game when it loses input focus.
-     */
-    void (*onWindowFocusChanged)(ANativeActivity* activity, int hasFocus);
-    
-    /**
-     * The drawing window for this native activity has been created.  You
-     * can use the given native window object to start drawing.
-     */
-    void (*onNativeWindowCreated)(ANativeActivity* activity, ANativeWindow* window);
-
-    /**
-     * The drawing window for this native activity has been resized.  You should
-     * retrieve the new size from the window and ensure that your rendering in
-     * it now matches.
-     */
-    void (*onNativeWindowResized)(ANativeActivity* activity, ANativeWindow* window);
-
-    /**
-     * The drawing window for this native activity needs to be redrawn.  To avoid
-     * transient artifacts during screen changes (such resizing after rotation),
-     * applications should not return from this function until they have finished
-     * drawing their window in its current state.
-     */
-    void (*onNativeWindowRedrawNeeded)(ANativeActivity* activity, ANativeWindow* window);
-
-    /**
-     * The drawing window for this native activity is going to be destroyed.
-     * You MUST ensure that you do not touch the window object after returning
-     * from this function: in the common case of drawing to the window from
-     * another thread, that means the implementation of this callback must
-     * properly synchronize with the other thread to stop its drawing before
-     * returning from here.
-     */
-    void (*onNativeWindowDestroyed)(ANativeActivity* activity, ANativeWindow* window);
-    
-    /**
-     * The input queue for this native activity's window has been created.
-     * You can use the given input queue to start retrieving input events.
-     */
-    void (*onInputQueueCreated)(ANativeActivity* activity, AInputQueue* queue);
-    
-    /**
-     * The input queue for this native activity's window is being destroyed.
-     * You should no longer try to reference this object upon returning from this
-     * function.
-     */
-    void (*onInputQueueDestroyed)(ANativeActivity* activity, AInputQueue* queue);
-
-    /**
-     * The rectangle in the window in which content should be placed has changed.
-     */
-    void (*onContentRectChanged)(ANativeActivity* activity, const ARect* rect);
-
-    /**
-     * The current device AConfiguration has changed.  The new configuration can
-     * be retrieved from assetManager.
-     */
-    void (*onConfigurationChanged)(ANativeActivity* activity);
-
-    /**
-     * The system is running low on memory.  Use this callback to release
-     * resources you do not need, to help the system avoid killing more
-     * important processes.
-     */
-    void (*onLowMemory)(ANativeActivity* activity);
-} ANativeActivityCallbacks;
-
-/**
- * This is the function that must be in the native code to instantiate the
- * application's native activity.  It is called with the activity instance (see
- * above); if the code is being instantiated from a previously saved instance,
- * the savedState will be non-NULL and point to the saved data.  You must make
- * any copy of this data you need -- it will be released after you return from
- * this function.
- */
-typedef void ANativeActivity_createFunc(ANativeActivity* activity,
-        void* savedState, size_t savedStateSize);
-
-/**
- * The name of the function that NativeInstance looks for when launching its
- * native code.  This is the default function that is used, you can specify
- * "android.app.func_name" string meta-data in your manifest to use a different
- * function.
- */
-extern ANativeActivity_createFunc ANativeActivity_onCreate;
-
-/**
- * Finish the given activity.  Its finish() method will be called, causing it
- * to be stopped and destroyed.  Note that this method can be called from
- * *any* thread; it will send a message to the main thread of the process
- * where the Java finish call will take place.
- */
-void ANativeActivity_finish(ANativeActivity* activity);
-
-/**
- * Change the window format of the given activity.  Calls getWindow().setFormat()
- * of the given activity.  Note that this method can be called from
- * *any* thread; it will send a message to the main thread of the process
- * where the Java finish call will take place.
- */
-void ANativeActivity_setWindowFormat(ANativeActivity* activity, int32_t format);
-
-/**
- * Change the window flags of the given activity.  Calls getWindow().setFlags()
- * of the given activity.  Note that this method can be called from
- * *any* thread; it will send a message to the main thread of the process
- * where the Java finish call will take place.  See window.h for flag constants.
- */
-void ANativeActivity_setWindowFlags(ANativeActivity* activity,
-        uint32_t addFlags, uint32_t removeFlags);
-
-/**
- * Flags for ANativeActivity_showSoftInput; see the Java InputMethodManager
- * API for documentation.
- */
-enum {
-    ANATIVEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT = 0x0001,
-    ANATIVEACTIVITY_SHOW_SOFT_INPUT_FORCED = 0x0002,
-};
-
-/**
- * Show the IME while in the given activity.  Calls InputMethodManager.showSoftInput()
- * for the given activity.  Note that this method can be called from
- * *any* thread; it will send a message to the main thread of the process
- * where the Java finish call will take place.
- */
-void ANativeActivity_showSoftInput(ANativeActivity* activity, uint32_t flags);
-
-/**
- * Flags for ANativeActivity_hideSoftInput; see the Java InputMethodManager
- * API for documentation.
- */
-enum {
-    ANATIVEACTIVITY_HIDE_SOFT_INPUT_IMPLICIT_ONLY = 0x0001,
-    ANATIVEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS = 0x0002,
-};
-
-/**
- * Hide the IME while in the given activity.  Calls InputMethodManager.hideSoftInput()
- * for the given activity.  Note that this method can be called from
- * *any* thread; it will send a message to the main thread of the process
- * where the Java finish call will take place.
- */
-void ANativeActivity_hideSoftInput(ANativeActivity* activity, uint32_t flags);
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif // ANDROID_NATIVE_ACTIVITY_H
-
diff --git a/ndk/platforms/android-3/arch-arm/lib/libc.so b/ndk/platforms/android-3/arch-arm/lib/libc.so
deleted file mode 100644
index 9714e97..0000000
--- a/ndk/platforms/android-3/arch-arm/lib/libc.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/lib/libdl.so b/ndk/platforms/android-3/arch-arm/lib/libdl.so
deleted file mode 100644
index e2a589c..0000000
--- a/ndk/platforms/android-3/arch-arm/lib/libdl.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/lib/liblog.so b/ndk/platforms/android-3/arch-arm/lib/liblog.so
deleted file mode 100644
index 92bf1a7..0000000
--- a/ndk/platforms/android-3/arch-arm/lib/liblog.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/lib/libm.so b/ndk/platforms/android-3/arch-arm/lib/libm.so
deleted file mode 100644
index 87f4446..0000000
--- a/ndk/platforms/android-3/arch-arm/lib/libm.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/lib/libstdc++.so b/ndk/platforms/android-3/arch-arm/lib/libstdc++.so
deleted file mode 100644
index d3d103f..0000000
--- a/ndk/platforms/android-3/arch-arm/lib/libstdc++.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/lib/libthread_db.so b/ndk/platforms/android-3/arch-arm/lib/libthread_db.so
deleted file mode 100644
index ea603f0..0000000
--- a/ndk/platforms/android-3/arch-arm/lib/libthread_db.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/lib/libz.so b/ndk/platforms/android-3/arch-arm/lib/libz.so
deleted file mode 100644
index f50a0ff..0000000
--- a/ndk/platforms/android-3/arch-arm/lib/libz.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-3/arch-arm/symbols/libc.so.txt b/ndk/platforms/android-3/arch-arm/symbols/libc.so.functions.txt
similarity index 89%
rename from ndk/platforms/android-3/arch-arm/symbols/libc.so.txt
rename to ndk/platforms/android-3/arch-arm/symbols/libc.so.functions.txt
index 1d13c72..814ce19 100644
--- a/ndk/platforms/android-3/arch-arm/symbols/libc.so.txt
+++ b/ndk/platforms/android-3/arch-arm/symbols/libc.so.functions.txt
@@ -1,10 +1,3 @@
-
-.ARM.extab
-.bss
-.data
-.data.rel.ro
-.rodata
-.text
 MD5_Final
 MD5_Init
 MD5_Update
@@ -12,9 +5,6 @@
 SHA1Init
 SHA1Transform
 SHA1Update
-_C_ctype_
-_C_tolower_
-_C_toupper_
 _Unwind_Backtrace
 _Unwind_Complete
 _Unwind_DeleteException
@@ -84,29 +74,14 @@
 __arc4_getbyte
 __assert
 __assert2
-__atexit
-__atexit_invalid
 __atexit_register_cleanup
-__atomic_cmpxchg
-__atomic_dec
-__atomic_inc
-__atomic_swap
 __b64_ntop
 __b64_pton
-__bionic_brk
 __brk
-__bss_end__
-__bss_start
-__bss_start__
 __clone
-__clz_tab
 __cmpdf2
 __cxa_atexit
-__cxa_begin_cleanup
-__cxa_call_unexpected
 __cxa_finalize
-__cxa_type_match
-__data_start
 __div0
 __divdf3
 __divdi3
@@ -115,9 +90,7 @@
 __dn_count_labels
 __dn_skipname
 __dorand48
-__dso_handle
 __dtoa
-__end__
 __eqdf2
 __errno
 __evAddTime
@@ -125,13 +98,10 @@
 __evConsIovec
 __evConsTime
 __evNowTime
-__evOptMonoTime
 __evSubTime
 __evTimeSpec
 __evTimeVal
 __evUTCTime
-__exidx_end
-__exidx_start
 __extendsfdf2
 __fcntl
 __fcntl64
@@ -145,13 +115,9 @@
 __fp_nquery
 __fp_query
 __fremovelock
-__futex_wait
-__futex_wake
 __gedf2
 __get_h_errno
-__get_pc
 __get_res_cache
-__get_sp
 __get_stack_base
 __get_thread
 __getcwd
@@ -172,7 +138,6 @@
 __hostalias
 __init_tls
 __ioctl
-__isthreaded
 __ledf2
 __libc_android_log_assert
 __libc_android_log_print
@@ -213,28 +178,18 @@
 __openat
 __p_cdname
 __p_cdnname
-__p_cert_syms
 __p_class
-__p_class_syms
-__p_default_section_syms
 __p_fqname
 __p_fqnname
-__p_key_syms
 __p_option
 __p_query
 __p_rcode
-__p_rcode_syms
 __p_secstodate
 __p_section
 __p_sockun
 __p_time
 __p_type
-__p_type_syms
-__p_update_section_syms
-__page_shift
-__page_size
 __pread64
-__progname
 __pthread_cleanup_pop
 __pthread_cleanup_push
 __pthread_clone
@@ -244,9 +199,6 @@
 __putlong
 __putshort
 __pwrite64
-__rand48_add
-__rand48_mult
-__rand48_seed
 __reboot
 __res_close
 __res_dnok
@@ -288,10 +240,7 @@
 __rt_sigaction
 __rt_sigprocmask
 __rt_sigtimedwait
-__sF
-__sFext
 __sclose
-__sdidinit
 __set_errno
 __set_syscall_errno
 __set_tls
@@ -299,7 +248,6 @@
 __sflush
 __sfp
 __sfvwrite
-__sglue
 __sigsuspend
 __sinit
 __slbexpand
@@ -309,7 +257,6 @@
 __srget
 __sseek
 __stack_chk_fail
-__stack_chk_guard
 __statfs64
 __subdf3
 __swbuf
@@ -321,7 +268,6 @@
 __sym_ston
 __syslog
 __system_properties_init
-__system_property_area__
 __system_property_find
 __system_property_find_nth
 __system_property_get
@@ -338,14 +284,8 @@
 __udivdi3
 __udivsi3
 __wait4
-_bss_end__
 _cleanup
-_ctype_
-_dns_gethtbyaddr
-_dns_gethtbyname
 _dorand48
-_edata
-_end
 _endhtent
 _exit
 _exit_thread
@@ -360,24 +300,9 @@
 _init_thread
 _longjmp
 _mktemp
-_nres
-_ns_flagdata
-_rand48_add
-_rand48_mult
-_rand48_seed
-_res_opcodes
-_resolv_cache_add
-_resolv_cache_create
-_resolv_cache_lookup
-_resolv_cache_reset
 _sethtent
 _setjmp
-_stack
-_thread_atexit_lock
-_thread_atexit_unlock
 _thread_created_hook
-_tolower_tab_
-_toupper_tab_
 abort
 accept
 access
@@ -455,15 +380,12 @@
 dlpvalloc
 dlvalloc
 dn_expand
-dns_change_prop
-dns_last_change_counter
 drand48
 dup
 dup2
 endpwent
 endservent
 endutent
-environ
 epoll_create
 epoll_ctl
 epoll_wait
@@ -475,8 +397,6 @@
 execve
 execvp
 exit
-fake_gmtime_r
-fake_localtime_r
 fchdir
 fchmod
 fchmodat
@@ -511,7 +431,6 @@
 fputws
 fread
 free
-free_malloc_leak_info
 freeaddrinfo
 freedtoa
 freopen
@@ -536,7 +455,6 @@
 fwprintf
 fwrite
 fwscanf
-gMallocLeakZygoteChild
 gai_strerror
 get_malloc_leak_info
 getaddrinfo
@@ -602,8 +520,6 @@
 gmtime64
 gmtime64_r
 gmtime_r
-h_errlist
-h_nerr
 herror
 hstrerror
 if_indextoname
@@ -714,11 +630,6 @@
 opendir
 openlog
 openlog_r
-optarg
-opterr
-optind
-optopt
-optreset
 pathconf
 pause
 pclose
@@ -814,7 +725,6 @@
 remove
 rename
 renameat
-res_get_dns_changed
 res_init
 res_mkquery
 res_need_init
@@ -944,7 +854,6 @@
 swscanf
 symlink
 sync
-sys_siglist
 syscall
 sysconf
 syslog
@@ -954,8 +863,6 @@
 tcgetpgrp
 tcsetpgrp
 tempnam
-the_key
-the_once
 time
 timegm64
 timelocal64
@@ -975,7 +882,6 @@
 towupper
 truncate
 ttyname
-tzname
 tzset
 umask
 umount
diff --git a/ndk/platforms/android-3/arch-arm/symbols/libc.so.variables.txt b/ndk/platforms/android-3/arch-arm/symbols/libc.so.variables.txt
new file mode 100644
index 0000000..e90d7af
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/symbols/libc.so.variables.txt
@@ -0,0 +1,48 @@
+_C_ctype_
+_C_tolower_
+_C_toupper_
+__atexit
+__atexit_invalid
+__bionic_brk
+__clz_tab
+__dso_handle
+__evOptMonoTime
+__isthreaded
+__p_cert_syms
+__p_class_syms
+__p_default_section_syms
+__p_key_syms
+__p_rcode_syms
+__p_type_syms
+__p_update_section_syms
+__page_shift
+__page_size
+__progname
+__rand48_add
+__rand48_mult
+__rand48_seed
+__sF
+__sFext
+__sdidinit
+__sglue
+__stack_chk_guard
+__system_property_area__
+_ctype_
+_nres
+_ns_flagdata
+_rand48_add
+_rand48_mult
+_rand48_seed
+_res_opcodes
+_tolower_tab_
+_toupper_tab_
+environ
+h_errlist
+h_nerr
+optarg
+opterr
+optind
+optopt
+optreset
+sys_siglist
+tzname
diff --git a/ndk/platforms/android-3/arch-arm/symbols/libdl.so.functions.txt b/ndk/platforms/android-3/arch-arm/symbols/libdl.so.functions.txt
new file mode 100644
index 0000000..44b52ce
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/symbols/libdl.so.functions.txt
@@ -0,0 +1,5 @@
+dl_unwind_find_exidx
+dlclose
+dlerror
+dlopen
+dlsym
diff --git a/ndk/platforms/android-3/arch-arm/symbols/libdl.so.variables.txt b/ndk/platforms/android-3/arch-arm/symbols/libdl.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/symbols/libdl.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/liblog.so.txt b/ndk/platforms/android-3/arch-arm/symbols/liblog.so.functions.txt
similarity index 75%
copy from ndk/platforms/android-9/arch-x86/symbols/liblog.so.txt
copy to ndk/platforms/android-3/arch-arm/symbols/liblog.so.functions.txt
index 1405a81..c5e51d0 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/liblog.so.txt
+++ b/ndk/platforms/android-3/arch-arm/symbols/liblog.so.functions.txt
@@ -1,10 +1,7 @@
 __android_log_assert
 __android_log_btwrite
-__android_log_buf_print
-__android_log_buf_write
 __android_log_bwrite
 __android_log_dev_available
 __android_log_print
 __android_log_vprint
 __android_log_write
-
diff --git a/ndk/platforms/android-3/arch-arm/symbols/liblog.so.variables.txt b/ndk/platforms/android-3/arch-arm/symbols/liblog.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/symbols/liblog.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libm.so.txt b/ndk/platforms/android-3/arch-arm/symbols/libm.so.functions.txt
similarity index 66%
copy from ndk/platforms/android-9/arch-x86/symbols/libm.so.txt
copy to ndk/platforms/android-3/arch-arm/symbols/libm.so.functions.txt
index 349f00f..29c368f 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libm.so.txt
+++ b/ndk/platforms/android-3/arch-arm/symbols/libm.so.functions.txt
@@ -1,9 +1,48 @@
+__addsf3
+__aeabi_cfcmpeq
+__aeabi_cfcmple
+__aeabi_cfrcmple
+__aeabi_d2lz
+__aeabi_d2uiz
+__aeabi_d2ulz
+__aeabi_dcmpun
+__aeabi_f2iz
+__aeabi_f2lz
+__aeabi_f2ulz
+__aeabi_fadd
+__aeabi_fcmpeq
+__aeabi_fcmpge
+__aeabi_fcmpgt
+__aeabi_fcmple
+__aeabi_fcmplt
+__aeabi_fcmpun
+__aeabi_fdiv
+__aeabi_fmul
+__aeabi_frsub
+__aeabi_fsub
+__aeabi_i2f
+__aeabi_l2f
+__aeabi_ui2f
+__aeabi_ul2f
+__cmpsf2
+__divsf3
+__eqsf2
 __exp__D
-__fedisableexcept
-__feenableexcept
+__fixdfdi
+__fixsfdi
+__fixsfsi
+__fixunsdfdi
+__fixunsdfsi
+__fixunssfdi
+__floatdisf
+__floatsisf
+__floatundisf
+__floatunsisf
 __fpclassifyd
 __fpclassifyf
 __fpclassifyl
+__gesf2
+__gtsf2
 __ieee754_rem_pio2
 __ieee754_rem_pio2f
 __isfinite
@@ -23,11 +62,17 @@
 __kernel_sindf
 __kernel_tan
 __kernel_tandf
+__lesf2
 __log__D
+__ltsf2
+__mulsf3
+__nesf2
 __signbit
 __signbitf
 __signbitl
-__test_sse
+__subsf3
+__unorddf2
+__unordsf2
 acos
 acosf
 acosh
@@ -72,11 +117,6 @@
 fdim
 fdimf
 fdiml
-fegetenv
-feholdexcept
-feraiseexcept
-fesetexceptflag
-feupdateenv
 finite
 finitef
 floor
@@ -111,6 +151,7 @@
 j1f
 jn
 jnf
+ldexp
 ldexpf
 ldexpl
 lgamma
@@ -155,15 +196,15 @@
 roundl
 scalb
 scalbf
+scalbln
+scalblnf
+scalblnl
 scalbn
 scalbnf
 scalbnl
 significand
 significandf
 sin
-sincos
-sincosf
-sincosl
 sinf
 sinh
 sinhf
@@ -183,8 +224,3 @@
 y1f
 yn
 ynf
-__FINI_ARRAY__
-__INIT_ARRAY__
-__fe_dfl_env
-__has_sse
-signgam
diff --git a/ndk/platforms/android-3/arch-arm/symbols/libm.so.variables.txt b/ndk/platforms/android-3/arch-arm/symbols/libm.so.variables.txt
new file mode 100644
index 0000000..a1b63fc
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/symbols/libm.so.variables.txt
@@ -0,0 +1,2 @@
+__fe_dfl_env
+signgam
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.txt b/ndk/platforms/android-3/arch-arm/symbols/libstdc++.so.functions.txt
similarity index 89%
copy from ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.txt
copy to ndk/platforms/android-3/arch-arm/symbols/libstdc++.so.functions.txt
index 920262d..3fb5bf7 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.txt
+++ b/ndk/platforms/android-3/arch-arm/symbols/libstdc++.so.functions.txt
@@ -21,6 +21,3 @@
 __cxa_guard_acquire
 __cxa_guard_release
 __cxa_pure_virtual
-_ZSt7nothrow
-__FINI_ARRAY__
-__INIT_ARRAY__
diff --git a/ndk/platforms/android-3/arch-arm/symbols/libstdc++.so.variables.txt b/ndk/platforms/android-3/arch-arm/symbols/libstdc++.so.variables.txt
new file mode 100644
index 0000000..d5aab66
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/symbols/libstdc++.so.variables.txt
@@ -0,0 +1,2 @@
+_ZSt7nothrow
+_ZTV9type_info
diff --git a/ndk/platforms/android-3/arch-arm/symbols/libthread_db.so.functions.txt b/ndk/platforms/android-3/arch-arm/symbols/libthread_db.so.functions.txt
new file mode 100644
index 0000000..473500d
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/symbols/libthread_db.so.functions.txt
@@ -0,0 +1,42 @@
+_Unwind_Backtrace
+_Unwind_Complete
+_Unwind_DeleteException
+_Unwind_ForcedUnwind
+_Unwind_GetCFA
+_Unwind_GetDataRelBase
+_Unwind_GetLanguageSpecificData
+_Unwind_GetRegionStart
+_Unwind_GetTextRelBase
+_Unwind_RaiseException
+_Unwind_Resume
+_Unwind_Resume_or_Rethrow
+_Unwind_VRS_Get
+_Unwind_VRS_Pop
+_Unwind_VRS_Set
+___Unwind_Backtrace
+___Unwind_ForcedUnwind
+___Unwind_RaiseException
+___Unwind_Resume
+___Unwind_Resume_or_Rethrow
+__aeabi_unwind_cpp_pr0
+__aeabi_unwind_cpp_pr1
+__aeabi_unwind_cpp_pr2
+__gnu_Unwind_Backtrace
+__gnu_Unwind_ForcedUnwind
+__gnu_Unwind_RaiseException
+__gnu_Unwind_Restore_VFP
+__gnu_Unwind_Resume
+__gnu_Unwind_Resume_or_Rethrow
+__gnu_Unwind_Save_VFP
+__gnu_unwind_execute
+__gnu_unwind_frame
+__restore_core_regs
+restore_core_regs
+td_symbol_list
+td_ta_event_addr
+td_ta_event_getmsg
+td_ta_new
+td_ta_set_event
+td_ta_thr_iter
+td_thr_event_enable
+td_thr_get_info
diff --git a/ndk/platforms/android-3/arch-arm/symbols/libthread_db.so.variables.txt b/ndk/platforms/android-3/arch-arm/symbols/libthread_db.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/symbols/libthread_db.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libz.so.txt b/ndk/platforms/android-3/arch-arm/symbols/libz.so.functions.txt
similarity index 73%
copy from ndk/platforms/android-9/arch-x86/symbols/libz.so.txt
copy to ndk/platforms/android-3/arch-arm/symbols/libz.so.functions.txt
index e35c7af..d61495b 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libz.so.txt
+++ b/ndk/platforms/android-3/arch-arm/symbols/libz.so.functions.txt
@@ -1,12 +1,15 @@
+_tr_align
+_tr_flush_block
+_tr_init
+_tr_stored_block
+_tr_tally
 adler32
 adler32_combine
-adler32_combine64
 compress
 compress2
 compressBound
 crc32
 crc32_combine
-crc32_combine64
 deflate
 deflateBound
 deflateCopy
@@ -20,11 +23,8 @@
 deflateSetHeader
 deflateTune
 get_crc_table
-gzbuffer
 gzclearerr
 gzclose
-gzclose_r
-gzclose_w
 gzdirect
 gzdopen
 gzeof
@@ -32,20 +32,15 @@
 gzflush
 gzgetc
 gzgets
-gzoffset
-gzoffset64
 gzopen
-gzopen64
 gzprintf
 gzputc
 gzputs
 gzread
 gzrewind
 gzseek
-gzseek64
 gzsetparams
 gztell
-gztell64
 gzungetc
 gzwrite
 inflate
@@ -57,20 +52,16 @@
 inflateGetHeader
 inflateInit2_
 inflateInit_
-inflateMark
 inflatePrime
 inflateReset
-inflateReset2
 inflateSetDictionary
 inflateSync
 inflateSyncPoint
-inflateUndermine
+inflate_fast
+inflate_table
 uncompress
 zError
+zcalloc
+zcfree
 zlibCompileFlags
 zlibVersion
-__FINI_ARRAY__
-__INIT_ARRAY__
-deflate_copyright
-inflate_copyright
-z_errmsg
diff --git a/ndk/platforms/android-3/arch-arm/symbols/libz.so.variables.txt b/ndk/platforms/android-3/arch-arm/symbols/libz.so.variables.txt
new file mode 100644
index 0000000..c653ee5
--- /dev/null
+++ b/ndk/platforms/android-3/arch-arm/symbols/libz.so.variables.txt
@@ -0,0 +1,5 @@
+_dist_code
+_length_code
+deflate_copyright
+inflate_copyright
+z_errmsg
diff --git a/ndk/platforms/android-4/arch-arm/lib/libGLESv1_CM.so b/ndk/platforms/android-4/arch-arm/lib/libGLESv1_CM.so
deleted file mode 100644
index f61f631..0000000
--- a/ndk/platforms/android-4/arch-arm/lib/libGLESv1_CM.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.txt b/ndk/platforms/android-4/arch-arm/symbols/libGLESv1_CM.so.functions.txt
similarity index 79%
copy from ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.txt
copy to ndk/platforms/android-4/arch-arm/symbols/libGLESv1_CM.so.functions.txt
index 7c53cfa..7e4c43a 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.txt
+++ b/ndk/platforms/android-4/arch-arm/symbols/libGLESv1_CM.so.functions.txt
@@ -6,7 +6,6 @@
 glBindFramebufferOES
 glBindRenderbufferOES
 glBindTexture
-glBindVertexArrayOES
 glBlendEquationOES
 glBlendEquationSeparateOES
 glBlendFunc
@@ -25,10 +24,8 @@
 glClearStencil
 glClientActiveTexture
 glClipPlanef
-glClipPlanefIMG
 glClipPlanefOES
 glClipPlanex
-glClipPlanexIMG
 glClipPlanexOES
 glColor4f
 glColor4ub
@@ -44,11 +41,9 @@
 glCullFace
 glCurrentPaletteMatrixOES
 glDeleteBuffers
-glDeleteFencesNV
 glDeleteFramebuffersOES
 glDeleteRenderbuffersOES
 glDeleteTextures
-glDeleteVertexArraysOES
 glDepthFunc
 glDepthMask
 glDepthRangef
@@ -57,8 +52,6 @@
 glDepthRangexOES
 glDisable
 glDisableClientState
-glDisableDriverControlQCOM
-glDiscardFramebufferEXT
 glDrawArrays
 glDrawElements
 glDrawTexfOES
@@ -73,22 +66,7 @@
 glEGLImageTargetTexture2DOES
 glEnable
 glEnableClientState
-glEnableDriverControlQCOM
-glEndTilingQCOM
-glExtGetBufferPointervQCOM
-glExtGetBuffersQCOM
-glExtGetFramebuffersQCOM
-glExtGetProgramBinarySourceQCOM
-glExtGetProgramsQCOM
-glExtGetRenderbuffersQCOM
-glExtGetShadersQCOM
-glExtGetTexLevelParameterivQCOM
-glExtGetTexSubImageQCOM
-glExtGetTexturesQCOM
-glExtIsProgramBinaryQCOM
-glExtTexObjectStateOverrideiQCOM
 glFinish
-glFinishFenceNV
 glFlush
 glFogf
 glFogfv
@@ -97,7 +75,6 @@
 glFogxv
 glFogxvOES
 glFramebufferRenderbufferOES
-glFramebufferTexture2DMultisampleIMG
 glFramebufferTexture2DOES
 glFrontFace
 glFrustumf
@@ -105,11 +82,9 @@
 glFrustumx
 glFrustumxOES
 glGenBuffers
-glGenFencesNV
 glGenFramebuffersOES
 glGenRenderbuffersOES
 glGenTextures
-glGenVertexArraysOES
 glGenerateMipmapOES
 glGetBooleanv
 glGetBufferParameteriv
@@ -118,10 +93,7 @@
 glGetClipPlanefOES
 glGetClipPlanex
 glGetClipPlanexOES
-glGetDriverControlStringQCOM
-glGetDriverControlsQCOM
 glGetError
-glGetFenceivNV
 glGetFixedv
 glGetFixedvOES
 glGetFloatv
@@ -150,11 +122,9 @@
 glHint
 glIsBuffer
 glIsEnabled
-glIsFenceNV
 glIsFramebufferOES
 glIsRenderbufferOES
 glIsTexture
-glIsVertexArrayOES
 glLightModelf
 glLightModelfv
 glLightModelx
@@ -184,13 +154,10 @@
 glMaterialxv
 glMaterialxvOES
 glMatrixIndexPointerOES
-glMatrixIndexPointerOESBounds
 glMatrixMode
 glMultMatrixf
 glMultMatrixx
 glMultMatrixxOES
-glMultiDrawArraysEXT
-glMultiDrawElementsEXT
 glMultiTexCoord4f
 glMultiTexCoord4x
 glMultiTexCoord4xOES
@@ -212,7 +179,6 @@
 glPointParameterxvOES
 glPointSize
 glPointSizePointerOES
-glPointSizePointerOESBounds
 glPointSizex
 glPointSizexOES
 glPolygonOffset
@@ -222,7 +188,6 @@
 glPushMatrix
 glQueryMatrixxOES
 glReadPixels
-glRenderbufferStorageMultisampleIMG
 glRenderbufferStorageOES
 glRotatef
 glRotatex
@@ -234,13 +199,10 @@
 glScalex
 glScalexOES
 glScissor
-glSetFenceNV
 glShadeModel
-glStartTilingQCOM
 glStencilFunc
 glStencilMask
 glStencilOp
-glTestFenceNV
 glTexCoordPointer
 glTexCoordPointerBounds
 glTexEnvf
@@ -275,6 +237,3 @@
 glVertexPointerBounds
 glViewport
 glWeightPointerOES
-glWeightPointerOESBounds
-__FINI_ARRAY__
-__INIT_ARRAY__
diff --git a/ndk/platforms/android-4/arch-arm/symbols/libGLESv1_CM.so.variables.txt b/ndk/platforms/android-4/arch-arm/symbols/libGLESv1_CM.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-4/arch-arm/symbols/libGLESv1_CM.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-5/arch-arm/lib/libGLESv2.so b/ndk/platforms/android-5/arch-arm/lib/libGLESv2.so
deleted file mode 100644
index fa6557b..0000000
--- a/ndk/platforms/android-5/arch-arm/lib/libGLESv2.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-5/arch-arm/lib/libc.so b/ndk/platforms/android-5/arch-arm/lib/libc.so
deleted file mode 100644
index 2483bf7..0000000
--- a/ndk/platforms/android-5/arch-arm/lib/libc.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.txt b/ndk/platforms/android-5/arch-arm/symbols/libGLESv2.so.functions.txt
similarity index 82%
copy from ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.txt
copy to ndk/platforms/android-5/arch-arm/symbols/libGLESv2.so.functions.txt
index d86b82c..34a7777 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.txt
+++ b/ndk/platforms/android-5/arch-arm/symbols/libGLESv2.so.functions.txt
@@ -6,7 +6,6 @@
 glBindFramebuffer
 glBindRenderbuffer
 glBindTexture
-glBindVertexArrayOES
 glBlendColor
 glBlendEquation
 glBlendEquationSeparate
@@ -28,8 +27,6 @@
 glCopyTexImage2D
 glCopyTexSubImage2D
 glCopyTexSubImage3DOES
-glCoverageMaskNV
-glCoverageOperationNV
 glCreateProgram
 glCreateShader
 glCullFace
@@ -41,7 +38,6 @@
 glDeleteRenderbuffers
 glDeleteShader
 glDeleteTextures
-glDeleteVertexArraysOES
 glDepthFunc
 glDepthMask
 glDepthRangef
@@ -49,7 +45,6 @@
 glDisable
 glDisableDriverControlQCOM
 glDisableVertexAttribArray
-glDiscardFramebufferEXT
 glDrawArrays
 glDrawElements
 glEGLImageTargetRenderbufferStorageOES
@@ -58,25 +53,11 @@
 glEnableDriverControlQCOM
 glEnableVertexAttribArray
 glEndPerfMonitorAMD
-glEndTilingQCOM
-glExtGetBufferPointervQCOM
-glExtGetBuffersQCOM
-glExtGetFramebuffersQCOM
-glExtGetProgramBinarySourceQCOM
-glExtGetProgramsQCOM
-glExtGetRenderbuffersQCOM
-glExtGetShadersQCOM
-glExtGetTexLevelParameterivQCOM
-glExtGetTexSubImageQCOM
-glExtGetTexturesQCOM
-glExtIsProgramBinaryQCOM
-glExtTexObjectStateOverrideiQCOM
 glFinish
 glFinishFenceNV
 glFlush
 glFramebufferRenderbuffer
 glFramebufferTexture2D
-glFramebufferTexture2DMultisampleIMG
 glFramebufferTexture3DOES
 glFrontFace
 glGenBuffers
@@ -85,7 +66,6 @@
 glGenPerfMonitorsAMD
 glGenRenderbuffers
 glGenTextures
-glGenVertexArraysOES
 glGenerateMipmap
 glGetActiveAttrib
 glGetActiveUniform
@@ -133,26 +113,21 @@
 glIsRenderbuffer
 glIsShader
 glIsTexture
-glIsVertexArrayOES
 glLineWidth
 glLinkProgram
 glMapBufferOES
-glMultiDrawArraysEXT
-glMultiDrawElementsEXT
 glPixelStorei
 glPolygonOffset
 glProgramBinaryOES
 glReadPixels
 glReleaseShaderCompiler
 glRenderbufferStorage
-glRenderbufferStorageMultisampleIMG
 glSampleCoverage
 glScissor
 glSelectPerfMonitorCountersAMD
 glSetFenceNV
 glShaderBinary
 glShaderSource
-glStartTilingQCOM
 glStencilFunc
 glStencilFuncSeparate
 glStencilMask
@@ -200,5 +175,3 @@
 glVertexAttrib4fv
 glVertexAttribPointer
 glViewport
-__FINI_ARRAY__
-__INIT_ARRAY__
diff --git a/ndk/platforms/android-5/arch-arm/symbols/libGLESv2.so.variables.txt b/ndk/platforms/android-5/arch-arm/symbols/libGLESv2.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-5/arch-arm/symbols/libGLESv2.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-5/arch-arm/symbols/libc.so.txt b/ndk/platforms/android-5/arch-arm/symbols/libc.so.functions.txt
similarity index 90%
rename from ndk/platforms/android-5/arch-arm/symbols/libc.so.txt
rename to ndk/platforms/android-5/arch-arm/symbols/libc.so.functions.txt
index 47e9383..9608503 100644
--- a/ndk/platforms/android-5/arch-arm/symbols/libc.so.txt
+++ b/ndk/platforms/android-5/arch-arm/symbols/libc.so.functions.txt
@@ -1,6 +1,3 @@
-
-.data.rel.ro
-.text
 MD5_Final
 MD5_Init
 MD5_Update
@@ -8,9 +5,6 @@
 SHA1Init
 SHA1Transform
 SHA1Update
-_C_ctype_
-_C_tolower_
-_C_toupper_
 _Unwind_Backtrace
 _Unwind_Complete
 _Unwind_DeleteException
@@ -93,29 +87,15 @@
 __arc4_getbyte
 __assert
 __assert2
-__atexit
-__atexit_invalid
 __atexit_register_cleanup
-__atomic_cmpxchg
-__atomic_dec
-__atomic_inc
-__atomic_swap
 __b64_ntop
 __b64_pton
-__bionic_brk
 __bionic_libgcc_compat_hooks
 __brk
-__bss_end__
-__bss_start
-__bss_start__
 __clone
 __cmpdf2
 __cxa_atexit
-__cxa_begin_cleanup
-__cxa_call_unexpected
 __cxa_finalize
-__cxa_type_match
-__data_start
 __div0
 __divdf3
 __divdi3
@@ -125,9 +105,7 @@
 __dn_count_labels
 __dn_skipname
 __dorand48
-__dso_handle
 __dtoa
-__end__
 __eqdf2
 __errno
 __evAddTime
@@ -135,13 +113,10 @@
 __evConsIovec
 __evConsTime
 __evNowTime
-__evOptMonoTime
 __evSubTime
 __evTimeSpec
 __evTimeVal
 __evUTCTime
-__exidx_end
-__exidx_start
 __extendsfdf2
 __fcntl
 __fcntl64
@@ -160,13 +135,9 @@
 __fp_nquery
 __fp_query
 __fremovelock
-__futex_wait
-__futex_wake
 __gedf2
 __get_h_errno
-__get_pc
 __get_res_cache
-__get_sp
 __get_stack_base
 __get_thread
 __getcwd
@@ -195,7 +166,6 @@
 __hostalias
 __init_tls
 __ioctl
-__isthreaded
 __ledf2
 __libc_android_abort
 __libc_android_log_assert
@@ -240,28 +210,18 @@
 __openat
 __p_cdname
 __p_cdnname
-__p_cert_syms
 __p_class
-__p_class_syms
-__p_default_section_syms
 __p_fqname
 __p_fqnname
-__p_key_syms
 __p_option
 __p_query
 __p_rcode
-__p_rcode_syms
 __p_secstodate
 __p_section
 __p_sockun
 __p_time
 __p_type
-__p_type_syms
-__p_update_section_syms
-__page_shift
-__page_size
 __pread64
-__progname
 __pthread_cleanup_pop
 __pthread_cleanup_push
 __pthread_clone
@@ -271,9 +231,6 @@
 __putlong
 __putshort
 __pwrite64
-__rand48_add
-__rand48_mult
-__rand48_seed
 __reboot
 __res_close
 __res_dnok
@@ -315,10 +272,7 @@
 __rt_sigaction
 __rt_sigprocmask
 __rt_sigtimedwait
-__sF
-__sFext
 __sclose
-__sdidinit
 __set_errno
 __set_syscall_errno
 __set_tls
@@ -326,7 +280,6 @@
 __sflush
 __sfp
 __sfvwrite
-__sglue
 __sigsuspend
 __sinit
 __slbexpand
@@ -336,7 +289,6 @@
 __srget
 __sseek
 __stack_chk_fail
-__stack_chk_guard
 __statfs64
 __subdf3
 __subsf3
@@ -349,7 +301,6 @@
 __sym_ston
 __syslog
 __system_properties_init
-__system_property_area__
 __system_property_find
 __system_property_find_nth
 __system_property_get
@@ -368,14 +319,8 @@
 __unorddf2
 __unordsf2
 __wait4
-_bss_end__
 _cleanup
-_ctype_
-_dns_gethtbyaddr
-_dns_gethtbyname
 _dorand48
-_edata
-_end
 _endhtent
 _exit
 _exit_thread
@@ -390,24 +335,9 @@
 _init_thread
 _longjmp
 _mktemp
-_nres
-_ns_flagdata
-_rand48_add
-_rand48_mult
-_rand48_seed
-_res_opcodes
-_resolv_cache_add
-_resolv_cache_create
-_resolv_cache_lookup
-_resolv_cache_reset
 _sethtent
 _setjmp
-_stack
-_thread_atexit_lock
-_thread_atexit_unlock
 _thread_created_hook
-_tolower_tab_
-_toupper_tab_
 abort
 accept
 access
@@ -485,15 +415,12 @@
 dlpvalloc
 dlvalloc
 dn_expand
-dns_change_prop
-dns_last_change_counter
 drand48
 dup
 dup2
 endpwent
 endservent
 endutent
-environ
 epoll_create
 epoll_ctl
 epoll_wait
@@ -505,8 +432,6 @@
 execve
 execvp
 exit
-fake_gmtime_r
-fake_localtime_r
 fchdir
 fchmod
 fchmodat
@@ -541,7 +466,6 @@
 fputws
 fread
 free
-free_malloc_leak_info
 freeaddrinfo
 freedtoa
 freopen
@@ -566,7 +490,6 @@
 fwprintf
 fwrite
 fwscanf
-gMallocLeakZygoteChild
 gai_strerror
 get_malloc_leak_info
 getaddrinfo
@@ -632,8 +555,6 @@
 gmtime64
 gmtime64_r
 gmtime_r
-h_errlist
-h_nerr
 herror
 hstrerror
 if_indextoname
@@ -688,7 +609,6 @@
 link
 listen
 lldiv
-load_domain_search_list
 localtime
 localtime64
 localtime64_r
@@ -745,11 +665,6 @@
 opendir
 openlog
 openlog_r
-optarg
-opterr
-optind
-optopt
-optreset
 pathconf
 pause
 pclose
@@ -848,7 +763,6 @@
 remove
 rename
 renameat
-res_get_dns_changed
 res_init
 res_mkquery
 res_need_init
@@ -979,7 +893,6 @@
 swscanf
 symlink
 sync
-sys_siglist
 syscall
 sysconf
 syslog
@@ -989,8 +902,6 @@
 tcgetpgrp
 tcsetpgrp
 tempnam
-the_key
-the_once
 time
 timegm64
 timelocal64
@@ -1010,7 +921,6 @@
 towupper
 truncate
 ttyname
-tzname
 tzset
 umask
 umount
diff --git a/ndk/platforms/android-5/arch-arm/symbols/libc.so.variables.txt b/ndk/platforms/android-5/arch-arm/symbols/libc.so.variables.txt
new file mode 100644
index 0000000..8f07523
--- /dev/null
+++ b/ndk/platforms/android-5/arch-arm/symbols/libc.so.variables.txt
@@ -0,0 +1,47 @@
+_C_ctype_
+_C_tolower_
+_C_toupper_
+__atexit
+__atexit_invalid
+__bionic_brk
+__dso_handle
+__evOptMonoTime
+__isthreaded
+__p_cert_syms
+__p_class_syms
+__p_default_section_syms
+__p_key_syms
+__p_rcode_syms
+__p_type_syms
+__p_update_section_syms
+__page_shift
+__page_size
+__progname
+__rand48_add
+__rand48_mult
+__rand48_seed
+__sF
+__sFext
+__sdidinit
+__sglue
+__stack_chk_guard
+__system_property_area__
+_ctype_
+_nres
+_ns_flagdata
+_rand48_add
+_rand48_mult
+_rand48_seed
+_res_opcodes
+_tolower_tab_
+_toupper_tab_
+environ
+h_errlist
+h_nerr
+optarg
+opterr
+optind
+optopt
+optreset
+sys_siglist
+tzname
diff --git a/ndk/platforms/android-8/arch-arm/lib/libc.so b/ndk/platforms/android-8/arch-arm/lib/libc.so
deleted file mode 100644
index b965d04..0000000
--- a/ndk/platforms/android-8/arch-arm/lib/libc.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-8/arch-arm/lib/libdl.so b/ndk/platforms/android-8/arch-arm/lib/libdl.so
deleted file mode 100644
index 3319c4c..0000000
--- a/ndk/platforms/android-8/arch-arm/lib/libdl.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-8/arch-arm/lib/libjnigraphics.so b/ndk/platforms/android-8/arch-arm/lib/libjnigraphics.so
deleted file mode 100755
index 4c21f4c..0000000
--- a/ndk/platforms/android-8/arch-arm/lib/libjnigraphics.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-8/arch-arm/symbols/libc.so.txt b/ndk/platforms/android-8/arch-arm/symbols/libc.so.functions.txt
similarity index 90%
copy from ndk/platforms/android-8/arch-arm/symbols/libc.so.txt
copy to ndk/platforms/android-8/arch-arm/symbols/libc.so.functions.txt
index b268233..88dd1b7 100644
--- a/ndk/platforms/android-8/arch-arm/symbols/libc.so.txt
+++ b/ndk/platforms/android-8/arch-arm/symbols/libc.so.functions.txt
@@ -1,6 +1,3 @@
-
-.data.rel.ro
-.text
 MD5_Final
 MD5_Init
 MD5_Update
@@ -8,9 +5,6 @@
 SHA1Init
 SHA1Transform
 SHA1Update
-_C_ctype_
-_C_tolower_
-_C_toupper_
 _Unwind_Backtrace
 _Unwind_Complete
 _Unwind_DeleteException
@@ -93,8 +87,6 @@
 __arc4_getbyte
 __assert
 __assert2
-__atexit
-__atexit_invalid
 __atexit_register_cleanup
 __atomic_cmpxchg
 __atomic_dec
@@ -102,21 +94,13 @@
 __atomic_swap
 __b64_ntop
 __b64_pton
-__bionic_brk
 __bionic_clone
 __bionic_clone_entry
 __bionic_libgcc_compat_hooks
 __brk
-__bss_end__
-__bss_start
-__bss_start__
 __cmpdf2
 __cxa_atexit
-__cxa_begin_cleanup
-__cxa_call_unexpected
 __cxa_finalize
-__cxa_type_match
-__data_start
 __div0
 __divdf3
 __divdi3
@@ -126,9 +110,7 @@
 __dn_count_labels
 __dn_skipname
 __dorand48
-__dso_handle
 __dtoa
-__end__
 __eqdf2
 __errno
 __evAddTime
@@ -136,13 +118,10 @@
 __evConsIovec
 __evConsTime
 __evNowTime
-__evOptMonoTime
 __evSubTime
 __evTimeSpec
 __evTimeVal
 __evUTCTime
-__exidx_end
-__exidx_start
 __extendsfdf2
 __fcntl
 __fcntl64
@@ -198,7 +177,6 @@
 __hostalias
 __init_tls
 __ioctl
-__isthreaded
 __ledf2
 __libc_android_abort
 __libc_android_log_assert
@@ -206,8 +184,6 @@
 __libc_android_log_vprint
 __libc_init
 __libc_init_common
-__libc_malloc_default_dispatch
-__libc_malloc_dispatch
 __libc_prenit
 __llseek
 __loc_aton
@@ -245,28 +221,18 @@
 __openat
 __p_cdname
 __p_cdnname
-__p_cert_syms
 __p_class
-__p_class_syms
-__p_default_section_syms
 __p_fqname
 __p_fqnname
-__p_key_syms
 __p_option
 __p_query
 __p_rcode
-__p_rcode_syms
 __p_secstodate
 __p_section
 __p_sockun
 __p_time
 __p_type
-__p_type_syms
-__p_update_section_syms
-__page_shift
-__page_size
 __pread64
-__progname
 __pthread_cleanup_pop
 __pthread_cleanup_push
 __pthread_clone
@@ -276,9 +242,6 @@
 __putlong
 __putshort
 __pwrite64
-__rand48_add
-__rand48_mult
-__rand48_seed
 __reboot
 __res_close
 __res_dnok
@@ -320,10 +283,7 @@
 __rt_sigaction
 __rt_sigprocmask
 __rt_sigtimedwait
-__sF
-__sFext
 __sclose
-__sdidinit
 __set_errno
 __set_syscall_errno
 __set_tls
@@ -334,7 +294,6 @@
 __sflush
 __sfp
 __sfvwrite
-__sglue
 __sigsuspend
 __sinit
 __slbexpand
@@ -344,7 +303,6 @@
 __srget
 __sseek
 __stack_chk_fail
-__stack_chk_guard
 __statfs64
 __subdf3
 __subsf3
@@ -358,7 +316,6 @@
 __sys_clone
 __syslog
 __system_properties_init
-__system_property_area__
 __system_property_find
 __system_property_find_nth
 __system_property_get
@@ -377,14 +334,8 @@
 __unorddf2
 __unordsf2
 __wait4
-_bss_end__
 _cleanup
-_ctype_
-_dns_gethtbyaddr
-_dns_gethtbyname
 _dorand48
-_edata
-_end
 _endhtent
 _exit
 _exit_thread
@@ -399,24 +350,9 @@
 _init_thread
 _longjmp
 _mktemp
-_nres
-_ns_flagdata
-_rand48_add
-_rand48_mult
-_rand48_seed
-_res_opcodes
-_resolv_cache_add
-_resolv_cache_create
-_resolv_cache_lookup
-_resolv_cache_reset
 _sethtent
 _setjmp
-_stack
-_thread_atexit_lock
-_thread_atexit_unlock
 _thread_created_hook
-_tolower_tab_
-_toupper_tab_
 abort
 accept
 access
@@ -477,7 +413,6 @@
 ctime64_r
 ctime_r
 daemon
-daylight
 delete_module
 difftime
 dirfd
@@ -503,8 +438,6 @@
 dlrealloc
 dlvalloc
 dn_expand
-dns_change_prop
-dns_last_change_counter
 drand48
 dup
 dup2
@@ -512,7 +445,6 @@
 endservent
 endusershell
 endutent
-environ
 epoll_create
 epoll_ctl
 epoll_wait
@@ -526,8 +458,6 @@
 execve
 execvp
 exit
-fake_gmtime_r
-fake_localtime_r
 fchdir
 fchmod
 fchmodat
@@ -563,7 +493,6 @@
 fputws
 fread
 free
-free_malloc_leak_info
 freeaddrinfo
 freedtoa
 freopen
@@ -593,9 +522,6 @@
 fwprintf
 fwrite
 fwscanf
-gAllocationsMutex
-gHashTable
-gMallocLeakZygoteChild
 gai_strerror
 get_malloc_leak_info
 getaddrinfo
@@ -662,8 +588,6 @@
 gmtime64
 gmtime64_r
 gmtime_r
-h_errlist
-h_nerr
 herror
 hstrerror
 if_indextoname
@@ -721,7 +645,6 @@
 link
 listen
 lldiv
-load_domain_search_list
 localtime
 localtime64
 localtime64_r
@@ -779,11 +702,6 @@
 opendir
 openlog
 openlog_r
-optarg
-opterr
-optind
-optopt
-optreset
 pathconf
 pause
 pclose
@@ -890,7 +808,6 @@
 remove
 rename
 renameat
-res_get_dns_changed
 res_init
 res_mkquery
 res_need_init
@@ -1023,8 +940,6 @@
 swscanf
 symlink
 sync
-sys_siglist
-sys_signame
 syscall
 sysconf
 syslog
@@ -1034,8 +949,6 @@
 tcgetpgrp
 tcsetpgrp
 tempnam
-the_key
-the_once
 time
 timegm64
 timelocal64
@@ -1045,7 +958,6 @@
 timer_gettime
 timer_settime
 times
-timezone
 tkill
 tmpfile
 tmpnam
@@ -1057,7 +969,6 @@
 truncate
 ttyname
 ttyname_r
-tzname
 tzset
 umask
 umount
diff --git a/ndk/platforms/android-8/arch-arm/symbols/libc.so.variables.txt b/ndk/platforms/android-8/arch-arm/symbols/libc.so.variables.txt
new file mode 100644
index 0000000..2cb26fe
--- /dev/null
+++ b/ndk/platforms/android-8/arch-arm/symbols/libc.so.variables.txt
@@ -0,0 +1,52 @@
+_C_ctype_
+_C_tolower_
+_C_toupper_
+__atexit
+__atexit_invalid
+__bionic_brk
+__dso_handle
+__evOptMonoTime
+__isthreaded
+__libc_malloc_default_dispatch
+__libc_malloc_dispatch
+__p_cert_syms
+__p_class_syms
+__p_default_section_syms
+__p_key_syms
+__p_rcode_syms
+__p_type_syms
+__p_update_section_syms
+__page_shift
+__page_size
+__progname
+__rand48_add
+__rand48_mult
+__rand48_seed
+__sF
+__sFext
+__sdidinit
+__sglue
+__stack_chk_guard
+__system_property_area__
+_ctype_
+_nres
+_ns_flagdata
+_rand48_add
+_rand48_mult
+_rand48_seed
+_res_opcodes
+_tolower_tab_
+_toupper_tab_
+daylight
+environ
+h_errlist
+h_nerr
+optarg
+opterr
+optind
+optopt
+optreset
+sys_siglist
+sys_signame
+timezone
+tzname
diff --git a/ndk/platforms/android-8/arch-arm/symbols/libdl.so.functions.txt b/ndk/platforms/android-8/arch-arm/symbols/libdl.so.functions.txt
new file mode 100644
index 0000000..bfbbe72
--- /dev/null
+++ b/ndk/platforms/android-8/arch-arm/symbols/libdl.so.functions.txt
@@ -0,0 +1,6 @@
+dl_unwind_find_exidx
+dladdr
+dlclose
+dlerror
+dlopen
+dlsym
diff --git a/ndk/platforms/android-8/arch-arm/symbols/libdl.so.variables.txt b/ndk/platforms/android-8/arch-arm/symbols/libdl.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-8/arch-arm/symbols/libdl.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.txt b/ndk/platforms/android-8/arch-arm/symbols/libjnigraphics.so.functions.txt
similarity index 70%
rename from ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.txt
rename to ndk/platforms/android-8/arch-arm/symbols/libjnigraphics.so.functions.txt
index 9cbc8c2..61612d4 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.txt
+++ b/ndk/platforms/android-8/arch-arm/symbols/libjnigraphics.so.functions.txt
@@ -1,5 +1,3 @@
 AndroidBitmap_getInfo
 AndroidBitmap_lockPixels
 AndroidBitmap_unlockPixels
-__FINI_ARRAY__
-__INIT_ARRAY__
diff --git a/ndk/platforms/android-8/arch-arm/symbols/libjnigraphics.so.variables.txt b/ndk/platforms/android-8/arch-arm/symbols/libjnigraphics.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-8/arch-arm/symbols/libjnigraphics.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-arm/lib/crtbegin_so.o b/ndk/platforms/android-9/arch-arm/lib/crtbegin_so.o
deleted file mode 100644
index 5230178..0000000
--- a/ndk/platforms/android-9/arch-arm/lib/crtbegin_so.o
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-arm/lib/crtend_so.o b/ndk/platforms/android-9/arch-arm/lib/crtend_so.o
deleted file mode 100644
index c54db97..0000000
--- a/ndk/platforms/android-9/arch-arm/lib/crtend_so.o
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-arm/lib/libEGL.so b/ndk/platforms/android-9/arch-arm/lib/libEGL.so
deleted file mode 100644
index 3d8c151..0000000
--- a/ndk/platforms/android-9/arch-arm/lib/libEGL.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-arm/lib/libOpenSLES.so b/ndk/platforms/android-9/arch-arm/lib/libOpenSLES.so
deleted file mode 100755
index 3f2ae90..0000000
--- a/ndk/platforms/android-9/arch-arm/lib/libOpenSLES.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-arm/lib/libandroid.so b/ndk/platforms/android-9/arch-arm/lib/libandroid.so
deleted file mode 100644
index 32d907b..0000000
--- a/ndk/platforms/android-9/arch-arm/lib/libandroid.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-arm/lib/libc.so b/ndk/platforms/android-9/arch-arm/lib/libc.so
deleted file mode 100644
index 5b3ba75..0000000
--- a/ndk/platforms/android-9/arch-arm/lib/libc.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-arm/symbols/libEGL.so.txt b/ndk/platforms/android-9/arch-arm/symbols/libEGL.so.functions.txt
similarity index 99%
rename from ndk/platforms/android-9/arch-arm/symbols/libEGL.so.txt
rename to ndk/platforms/android-9/arch-arm/symbols/libEGL.so.functions.txt
index cc71131..12d92a3 100644
--- a/ndk/platforms/android-9/arch-arm/symbols/libEGL.so.txt
+++ b/ndk/platforms/android-9/arch-arm/symbols/libEGL.so.functions.txt
@@ -37,4 +37,3 @@
 eglWaitClient
 eglWaitGL
 eglWaitNative
-
diff --git a/ndk/platforms/android-9/arch-arm/symbols/libEGL.so.variables.txt b/ndk/platforms/android-9/arch-arm/symbols/libEGL.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-9/arch-arm/symbols/libEGL.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.functions.txt b/ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.functions.txt
new file mode 100644
index 0000000..f69a3e5
--- /dev/null
+++ b/ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.functions.txt
@@ -0,0 +1,3 @@
+slCreateEngine
+slQueryNumSupportedEngineInterfaces
+slQuerySupportedEngineInterfaces
diff --git a/ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.txt b/ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.variables.txt
similarity index 91%
rename from ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.txt
rename to ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.variables.txt
index b42d1ee..0c94828 100644
--- a/ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.txt
+++ b/ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.variables.txt
@@ -1,6 +1,3 @@
-slCreateEngine
-slQueryNumSupportedEngineInterfaces
-slQuerySupportedEngineInterfaces
 SL_IID_3DCOMMIT
 SL_IID_3DDOPPLER
 SL_IID_3DGROUPING
diff --git a/ndk/platforms/android-9/arch-arm/symbols/libandroid.so.txt b/ndk/platforms/android-9/arch-arm/symbols/libandroid.so.functions.txt
similarity index 99%
rename from ndk/platforms/android-9/arch-arm/symbols/libandroid.so.txt
rename to ndk/platforms/android-9/arch-arm/symbols/libandroid.so.functions.txt
index e6d17fe..4438c5e 100644
--- a/ndk/platforms/android-9/arch-arm/symbols/libandroid.so.txt
+++ b/ndk/platforms/android-9/arch-arm/symbols/libandroid.so.functions.txt
@@ -146,4 +146,3 @@
 AStorageManager_mountObb
 AStorageManager_new
 AStorageManager_unmountObb
-
diff --git a/ndk/platforms/android-9/arch-arm/symbols/libandroid.so.variables.txt b/ndk/platforms/android-9/arch-arm/symbols/libandroid.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-9/arch-arm/symbols/libandroid.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-8/arch-arm/symbols/libc.so.txt b/ndk/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
similarity index 90%
rename from ndk/platforms/android-8/arch-arm/symbols/libc.so.txt
rename to ndk/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
index b268233..c1c4358 100644
--- a/ndk/platforms/android-8/arch-arm/symbols/libc.so.txt
+++ b/ndk/platforms/android-9/arch-arm/symbols/libc.so.functions.txt
@@ -1,6 +1,3 @@
-
-.data.rel.ro
-.text
 MD5_Final
 MD5_Init
 MD5_Update
@@ -8,9 +5,6 @@
 SHA1Init
 SHA1Transform
 SHA1Update
-_C_ctype_
-_C_tolower_
-_C_toupper_
 _Unwind_Backtrace
 _Unwind_Complete
 _Unwind_DeleteException
@@ -93,8 +87,6 @@
 __arc4_getbyte
 __assert
 __assert2
-__atexit
-__atexit_invalid
 __atexit_register_cleanup
 __atomic_cmpxchg
 __atomic_dec
@@ -102,21 +94,13 @@
 __atomic_swap
 __b64_ntop
 __b64_pton
-__bionic_brk
 __bionic_clone
 __bionic_clone_entry
 __bionic_libgcc_compat_hooks
 __brk
-__bss_end__
-__bss_start
-__bss_start__
 __cmpdf2
 __cxa_atexit
-__cxa_begin_cleanup
-__cxa_call_unexpected
 __cxa_finalize
-__cxa_type_match
-__data_start
 __div0
 __divdf3
 __divdi3
@@ -126,9 +110,7 @@
 __dn_count_labels
 __dn_skipname
 __dorand48
-__dso_handle
 __dtoa
-__end__
 __eqdf2
 __errno
 __evAddTime
@@ -136,13 +118,10 @@
 __evConsIovec
 __evConsTime
 __evNowTime
-__evOptMonoTime
 __evSubTime
 __evTimeSpec
 __evTimeVal
 __evUTCTime
-__exidx_end
-__exidx_start
 __extendsfdf2
 __fcntl
 __fcntl64
@@ -161,10 +140,13 @@
 __fp_nquery
 __fp_query
 __fremovelock
+__fstatfs64
 __futex_syscall3
 __futex_syscall4
 __futex_wait
+__futex_wait_ex
 __futex_wake
+__futex_wake_ex
 __gedf2
 __get_h_errno
 __get_pc
@@ -198,17 +180,15 @@
 __hostalias
 __init_tls
 __ioctl
-__isthreaded
 __ledf2
 __libc_android_abort
 __libc_android_log_assert
 __libc_android_log_print
 __libc_android_log_vprint
+__libc_fini
 __libc_init
 __libc_init_common
-__libc_malloc_default_dispatch
-__libc_malloc_dispatch
-__libc_prenit
+__libc_preinit
 __llseek
 __loc_aton
 __loc_ntoa
@@ -245,28 +225,18 @@
 __openat
 __p_cdname
 __p_cdnname
-__p_cert_syms
 __p_class
-__p_class_syms
-__p_default_section_syms
 __p_fqname
 __p_fqnname
-__p_key_syms
 __p_option
 __p_query
 __p_rcode
-__p_rcode_syms
 __p_secstodate
 __p_section
 __p_sockun
 __p_time
 __p_type
-__p_type_syms
-__p_update_section_syms
-__page_shift
-__page_size
 __pread64
-__progname
 __pthread_cleanup_pop
 __pthread_cleanup_push
 __pthread_clone
@@ -276,9 +246,6 @@
 __putlong
 __putshort
 __pwrite64
-__rand48_add
-__rand48_mult
-__rand48_seed
 __reboot
 __res_close
 __res_dnok
@@ -320,10 +287,7 @@
 __rt_sigaction
 __rt_sigprocmask
 __rt_sigtimedwait
-__sF
-__sFext
 __sclose
-__sdidinit
 __set_errno
 __set_syscall_errno
 __set_tls
@@ -334,7 +298,6 @@
 __sflush
 __sfp
 __sfvwrite
-__sglue
 __sigsuspend
 __sinit
 __slbexpand
@@ -344,7 +307,6 @@
 __srget
 __sseek
 __stack_chk_fail
-__stack_chk_guard
 __statfs64
 __subdf3
 __subsf3
@@ -358,7 +320,6 @@
 __sys_clone
 __syslog
 __system_properties_init
-__system_property_area__
 __system_property_find
 __system_property_find_nth
 __system_property_get
@@ -377,14 +338,9 @@
 __unorddf2
 __unordsf2
 __wait4
-_bss_end__
+__waitid
 _cleanup
-_ctype_
-_dns_gethtbyaddr
-_dns_gethtbyname
 _dorand48
-_edata
-_end
 _endhtent
 _exit
 _exit_thread
@@ -399,24 +355,9 @@
 _init_thread
 _longjmp
 _mktemp
-_nres
-_ns_flagdata
-_rand48_add
-_rand48_mult
-_rand48_seed
-_res_opcodes
-_resolv_cache_add
-_resolv_cache_create
-_resolv_cache_lookup
-_resolv_cache_reset
 _sethtent
 _setjmp
-_stack
-_thread_atexit_lock
-_thread_atexit_unlock
 _thread_created_hook
-_tolower_tab_
-_toupper_tab_
 abort
 accept
 access
@@ -477,7 +418,6 @@
 ctime64_r
 ctime_r
 daemon
-daylight
 delete_module
 difftime
 dirfd
@@ -503,8 +443,6 @@
 dlrealloc
 dlvalloc
 dn_expand
-dns_change_prop
-dns_last_change_counter
 drand48
 dup
 dup2
@@ -512,13 +450,15 @@
 endservent
 endusershell
 endutent
-environ
 epoll_create
 epoll_ctl
 epoll_wait
 erand48
 err
 errx
+eventfd
+eventfd_read
+eventfd_write
 execl
 execle
 execlp
@@ -526,8 +466,6 @@
 execve
 execvp
 exit
-fake_gmtime_r
-fake_localtime_r
 fchdir
 fchmod
 fchmodat
@@ -535,6 +473,7 @@
 fchownat
 fclose
 fcntl
+fdatasync
 fdopen
 fdopendir
 fdprintf
@@ -563,7 +502,6 @@
 fputws
 fread
 free
-free_malloc_leak_info
 freeaddrinfo
 freedtoa
 freopen
@@ -593,9 +531,6 @@
 fwprintf
 fwrite
 fwscanf
-gAllocationsMutex
-gHashTable
-gMallocLeakZygoteChild
 gai_strerror
 get_malloc_leak_info
 getaddrinfo
@@ -662,8 +597,6 @@
 gmtime64
 gmtime64_r
 gmtime_r
-h_errlist
-h_nerr
 herror
 hstrerror
 if_indextoname
@@ -721,7 +654,6 @@
 link
 listen
 lldiv
-load_domain_search_list
 localtime
 localtime64
 localtime64_r
@@ -779,16 +711,12 @@
 opendir
 openlog
 openlog_r
-optarg
-opterr
-optind
-optopt
-optreset
 pathconf
 pause
 pclose
 perror
 pipe
+pipe2
 poll
 popen
 prctl
@@ -852,7 +780,21 @@
 pthread_mutexattr_setpshared
 pthread_mutexattr_settype
 pthread_once
+pthread_rwlock_destroy
+pthread_rwlock_init
+pthread_rwlock_rdlock
+pthread_rwlock_timedrdlock
+pthread_rwlock_timedwrlock
+pthread_rwlock_tryrdlock
+pthread_rwlock_trywrlock
+pthread_rwlock_unlock
+pthread_rwlock_wrlock
+pthread_rwlockattr_destroy
+pthread_rwlockattr_getpshared
+pthread_rwlockattr_init
+pthread_rwlockattr_setpshared
 pthread_self
+pthread_setname_np
 pthread_setschedparam
 pthread_setspecific
 pthread_sigmask
@@ -890,7 +832,6 @@
 remove
 rename
 renameat
-res_get_dns_changed
 res_init
 res_mkquery
 res_need_init
@@ -1023,10 +964,9 @@
 swscanf
 symlink
 sync
-sys_siglist
-sys_signame
 syscall
 sysconf
+sysinfo
 syslog
 syslog_r
 system
@@ -1034,8 +974,6 @@
 tcgetpgrp
 tcsetpgrp
 tempnam
-the_key
-the_once
 time
 timegm64
 timelocal64
@@ -1045,7 +983,6 @@
 timer_gettime
 timer_settime
 times
-timezone
 tkill
 tmpfile
 tmpnam
@@ -1057,7 +994,6 @@
 truncate
 ttyname
 ttyname_r
-tzname
 tzset
 umask
 umount
@@ -1101,18 +1037,26 @@
 waitpid
 warn
 warnx
+wcpcpy
+wcpncpy
 wcrtomb
+wcscasecmp
 wcscat
 wcschr
 wcscmp
 wcscoll
 wcscpy
 wcscspn
+wcsdup
 wcsftime
+wcslcat
+wcslcpy
 wcslen
+wcsncasecmp
 wcsncat
 wcsncmp
 wcsncpy
+wcsnlen
 wcspbrk
 wcsrchr
 wcsrtombs
diff --git a/ndk/platforms/android-9/arch-arm/symbols/libc.so.variables.txt b/ndk/platforms/android-9/arch-arm/symbols/libc.so.variables.txt
new file mode 100644
index 0000000..ce5ef63
--- /dev/null
+++ b/ndk/platforms/android-9/arch-arm/symbols/libc.so.variables.txt
@@ -0,0 +1,51 @@
+_C_ctype_
+_C_tolower_
+_C_toupper_
+__atexit
+__atexit_invalid
+__bionic_brk
+__evOptMonoTime
+__isthreaded
+__libc_malloc_default_dispatch
+__libc_malloc_dispatch
+__p_cert_syms
+__p_class_syms
+__p_default_section_syms
+__p_key_syms
+__p_rcode_syms
+__p_type_syms
+__p_update_section_syms
+__page_shift
+__page_size
+__progname
+__rand48_add
+__rand48_mult
+__rand48_seed
+__sF
+__sFext
+__sdidinit
+__sglue
+__stack_chk_guard
+__system_property_area__
+_ctype_
+_nres
+_ns_flagdata
+_rand48_add
+_rand48_mult
+_rand48_seed
+_res_opcodes
+_tolower_tab_
+_toupper_tab_
+daylight
+environ
+h_errlist
+h_nerr
+optarg
+opterr
+optind
+optopt
+optreset
+sys_siglist
+sys_signame
+timezone
+tzname
diff --git a/ndk/platforms/android-9/arch-x86/lib/libEGL.so b/ndk/platforms/android-9/arch-x86/lib/libEGL.so
deleted file mode 100755
index 49020a9..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/libEGL.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libGLESv1_CM.so b/ndk/platforms/android-9/arch-x86/lib/libGLESv1_CM.so
deleted file mode 100755
index 83ddd59..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/libGLESv1_CM.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libGLESv2.so b/ndk/platforms/android-9/arch-x86/lib/libGLESv2.so
deleted file mode 100755
index 7c72567..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/libGLESv2.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libOpenSLES.so b/ndk/platforms/android-9/arch-x86/lib/libOpenSLES.so
deleted file mode 100755
index de81e57..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/libOpenSLES.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libandroid.so b/ndk/platforms/android-9/arch-x86/lib/libandroid.so
deleted file mode 100755
index 419d414..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/libandroid.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libc.so b/ndk/platforms/android-9/arch-x86/lib/libc.so
deleted file mode 100755
index fd6c188..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/libc.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libdl.so b/ndk/platforms/android-9/arch-x86/lib/libdl.so
deleted file mode 100755
index c31fd46..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/libdl.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libjnigraphics.so b/ndk/platforms/android-9/arch-x86/lib/libjnigraphics.so
deleted file mode 100755
index 2a0494f..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/libjnigraphics.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/liblog.so b/ndk/platforms/android-9/arch-x86/lib/liblog.so
deleted file mode 100755
index 6ab1fd2..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/liblog.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libm.so b/ndk/platforms/android-9/arch-x86/lib/libm.so
deleted file mode 100755
index 78c3def..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/libm.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libstdc++.so b/ndk/platforms/android-9/arch-x86/lib/libstdc++.so
deleted file mode 100755
index 248dc48..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/libstdc++.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-x86/lib/libz.so b/ndk/platforms/android-9/arch-x86/lib/libz.so
deleted file mode 100755
index 384e8c4..0000000
--- a/ndk/platforms/android-9/arch-x86/lib/libz.so
+++ /dev/null
Binary files differ
diff --git a/ndk/platforms/android-9/arch-arm/symbols/libEGL.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libEGL.so.functions.txt
similarity index 99%
copy from ndk/platforms/android-9/arch-arm/symbols/libEGL.so.txt
copy to ndk/platforms/android-9/arch-x86/symbols/libEGL.so.functions.txt
index cc71131..12d92a3 100644
--- a/ndk/platforms/android-9/arch-arm/symbols/libEGL.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/libEGL.so.functions.txt
@@ -37,4 +37,3 @@
 eglWaitClient
 eglWaitGL
 eglWaitNative
-
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libEGL.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libEGL.so.txt
deleted file mode 100644
index 8550335..0000000
--- a/ndk/platforms/android-9/arch-x86/symbols/libEGL.so.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-eglBindAPI
-eglBindTexImage
-eglChooseConfig
-eglCopyBuffers
-eglCreateContext
-eglCreateImageKHR
-eglCreatePbufferFromClientBuffer
-eglCreatePbufferSurface
-eglCreatePixmapSurface
-eglCreateWindowSurface
-eglDestroyContext
-eglDestroyImageKHR
-eglDestroySurface
-eglGetConfigAttrib
-eglGetConfigs
-eglGetCurrentContext
-eglGetCurrentDisplay
-eglGetCurrentSurface
-eglGetDisplay
-eglGetError
-eglGetProcAddress
-eglInitialize
-eglLockSurfaceKHR
-eglMakeCurrent
-eglQueryAPI
-eglQueryContext
-eglQueryString
-eglQuerySurface
-eglReleaseTexImage
-eglReleaseThread
-eglSetSwapRectangleANDROID
-eglSurfaceAttrib
-eglSwapBuffers
-eglSwapInterval
-eglTerminate
-eglUnlockSurfaceKHR
-eglWaitClient
-eglWaitGL
-eglWaitNative
-__FINI_ARRAY__
-__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libEGL.so.variables.txt b/ndk/platforms/android-9/arch-x86/symbols/libEGL.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libEGL.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.functions.txt
similarity index 98%
rename from ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.txt
rename to ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.functions.txt
index 7c53cfa..8dc96a4 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.functions.txt
@@ -276,5 +276,3 @@
 glViewport
 glWeightPointerOES
 glWeightPointerOESBounds
-__FINI_ARRAY__
-__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.variables.txt b/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libGLESv1_CM.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.functions.txt
similarity index 98%
rename from ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.txt
rename to ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.functions.txt
index d86b82c..13c4644 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.functions.txt
@@ -200,5 +200,3 @@
 glVertexAttrib4fv
 glVertexAttribPointer
 glViewport
-__FINI_ARRAY__
-__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.variables.txt b/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libGLESv2.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.functions.txt b/ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.functions.txt
new file mode 100644
index 0000000..f69a3e5
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.functions.txt
@@ -0,0 +1,3 @@
+slCreateEngine
+slQueryNumSupportedEngineInterfaces
+slQuerySupportedEngineInterfaces
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.txt
deleted file mode 100644
index b42d1ee..0000000
--- a/ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-slCreateEngine
-slQueryNumSupportedEngineInterfaces
-slQuerySupportedEngineInterfaces
-SL_IID_3DCOMMIT
-SL_IID_3DDOPPLER
-SL_IID_3DGROUPING
-SL_IID_3DLOCATION
-SL_IID_3DMACROSCOPIC
-SL_IID_3DSOURCE
-SL_IID_ANDROIDCONFIGURATION
-SL_IID_ANDROIDEFFECT
-SL_IID_ANDROIDEFFECTCAPABILITIES
-SL_IID_ANDROIDEFFECTSEND
-SL_IID_ANDROIDSIMPLEBUFFERQUEUE
-SL_IID_AUDIODECODERCAPABILITIES
-SL_IID_AUDIOENCODER
-SL_IID_AUDIOENCODERCAPABILITIES
-SL_IID_AUDIOIODEVICECAPABILITIES
-SL_IID_BASSBOOST
-SL_IID_BUFFERQUEUE
-SL_IID_DEVICEVOLUME
-SL_IID_DYNAMICINTERFACEMANAGEMENT
-SL_IID_DYNAMICSOURCE
-SL_IID_EFFECTSEND
-SL_IID_ENGINE
-SL_IID_ENGINECAPABILITIES
-SL_IID_ENVIRONMENTALREVERB
-SL_IID_EQUALIZER
-SL_IID_LED
-SL_IID_METADATAEXTRACTION
-SL_IID_METADATATRAVERSAL
-SL_IID_MIDIMESSAGE
-SL_IID_MIDIMUTESOLO
-SL_IID_MIDITEMPO
-SL_IID_MIDITIME
-SL_IID_MUTESOLO
-SL_IID_NULL
-SL_IID_OBJECT
-SL_IID_OUTPUTMIX
-SL_IID_PITCH
-SL_IID_PLAY
-SL_IID_PLAYBACKRATE
-SL_IID_PREFETCHSTATUS
-SL_IID_PRESETREVERB
-SL_IID_RATEPITCH
-SL_IID_RECORD
-SL_IID_SEEK
-SL_IID_THREADSYNC
-SL_IID_VIBRA
-SL_IID_VIRTUALIZER
-SL_IID_VISUALIZATION
-SL_IID_VOLUME
diff --git a/ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.variables.txt
similarity index 91%
copy from ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.txt
copy to ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.variables.txt
index b42d1ee..0c94828 100644
--- a/ndk/platforms/android-9/arch-arm/symbols/libOpenSLES.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/libOpenSLES.so.variables.txt
@@ -1,6 +1,3 @@
-slCreateEngine
-slQueryNumSupportedEngineInterfaces
-slQuerySupportedEngineInterfaces
 SL_IID_3DCOMMIT
 SL_IID_3DDOPPLER
 SL_IID_3DGROUPING
diff --git a/ndk/platforms/android-9/arch-arm/symbols/libandroid.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libandroid.so.functions.txt
similarity index 99%
copy from ndk/platforms/android-9/arch-arm/symbols/libandroid.so.txt
copy to ndk/platforms/android-9/arch-x86/symbols/libandroid.so.functions.txt
index e6d17fe..4438c5e 100644
--- a/ndk/platforms/android-9/arch-arm/symbols/libandroid.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/libandroid.so.functions.txt
@@ -146,4 +146,3 @@
 AStorageManager_mountObb
 AStorageManager_new
 AStorageManager_unmountObb
-
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libandroid.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libandroid.so.txt
deleted file mode 100644
index 80178a3..0000000
--- a/ndk/platforms/android-9/arch-x86/symbols/libandroid.so.txt
+++ /dev/null
@@ -1,150 +0,0 @@
-AAssetDir_close
-AAssetDir_getNextFileName
-AAssetDir_rewind
-AAssetManager_fromJava
-AAssetManager_open
-AAssetManager_openDir
-AAsset_close
-AAsset_getBuffer
-AAsset_getLength
-AAsset_getRemainingLength
-AAsset_isAllocated
-AAsset_openFileDescriptor
-AAsset_read
-AAsset_seek
-AConfiguration_copy
-AConfiguration_delete
-AConfiguration_diff
-AConfiguration_fromAssetManager
-AConfiguration_getCountry
-AConfiguration_getDensity
-AConfiguration_getKeyboard
-AConfiguration_getKeysHidden
-AConfiguration_getLanguage
-AConfiguration_getMcc
-AConfiguration_getMnc
-AConfiguration_getNavHidden
-AConfiguration_getNavigation
-AConfiguration_getOrientation
-AConfiguration_getScreenLong
-AConfiguration_getScreenSize
-AConfiguration_getSdkVersion
-AConfiguration_getTouchscreen
-AConfiguration_getUiModeNight
-AConfiguration_getUiModeType
-AConfiguration_isBetterThan
-AConfiguration_match
-AConfiguration_new
-AConfiguration_setCountry
-AConfiguration_setDensity
-AConfiguration_setKeyboard
-AConfiguration_setKeysHidden
-AConfiguration_setLanguage
-AConfiguration_setMcc
-AConfiguration_setMnc
-AConfiguration_setNavHidden
-AConfiguration_setNavigation
-AConfiguration_setOrientation
-AConfiguration_setScreenLong
-AConfiguration_setScreenSize
-AConfiguration_setSdkVersion
-AConfiguration_setTouchscreen
-AConfiguration_setUiModeNight
-AConfiguration_setUiModeType
-AInputEvent_getDeviceId
-AInputEvent_getSource
-AInputEvent_getType
-AInputQueue_attachLooper
-AInputQueue_detachLooper
-AInputQueue_finishEvent
-AInputQueue_getEvent
-AInputQueue_hasEvents
-AInputQueue_preDispatchEvent
-AKeyEvent_getAction
-AKeyEvent_getDownTime
-AKeyEvent_getEventTime
-AKeyEvent_getFlags
-AKeyEvent_getKeyCode
-AKeyEvent_getMetaState
-AKeyEvent_getRepeatCount
-AKeyEvent_getScanCode
-ALooper_acquire
-ALooper_addFd
-ALooper_forThread
-ALooper_pollAll
-ALooper_pollOnce
-ALooper_prepare
-ALooper_release
-ALooper_removeFd
-ALooper_wake
-AMotionEvent_getAction
-AMotionEvent_getDownTime
-AMotionEvent_getEdgeFlags
-AMotionEvent_getEventTime
-AMotionEvent_getFlags
-AMotionEvent_getHistoricalEventTime
-AMotionEvent_getHistoricalPressure
-AMotionEvent_getHistoricalSize
-AMotionEvent_getHistoricalX
-AMotionEvent_getHistoricalY
-AMotionEvent_getHistorySize
-AMotionEvent_getMetaState
-AMotionEvent_getOrientation
-AMotionEvent_getPointerCount
-AMotionEvent_getPointerId
-AMotionEvent_getPressure
-AMotionEvent_getRawX
-AMotionEvent_getRawY
-AMotionEvent_getSize
-AMotionEvent_getToolMajor
-AMotionEvent_getToolMinor
-AMotionEvent_getTouchMajor
-AMotionEvent_getTouchMinor
-AMotionEvent_getX
-AMotionEvent_getXOffset
-AMotionEvent_getXPrecision
-AMotionEvent_getY
-AMotionEvent_getYOffset
-AMotionEvent_getYPrecision
-ANativeActivity_finish
-ANativeActivity_hideSoftInput
-ANativeActivity_setWindowFlags
-ANativeActivity_setWindowFormat
-ANativeActivity_showSoftInput
-ANativeWindow_acquire
-ANativeWindow_fromSurface
-ANativeWindow_getFormat
-ANativeWindow_getHeight
-ANativeWindow_getWidth
-ANativeWindow_lock
-ANativeWindow_release
-ANativeWindow_setBuffersGeometry
-ANativeWindow_unlockAndPost
-AObbInfo_delete
-AObbInfo_getFlags
-AObbInfo_getPackageName
-AObbInfo_getVersion
-AObbScanner_getObbInfo
-ASensorEventQueue_disableSensor
-ASensorEventQueue_enableSensor
-ASensorEventQueue_getEvents
-ASensorEventQueue_hasEvents
-ASensorEventQueue_setEventRate
-ASensorManager_createEventQueue
-ASensorManager_destroyEventQueue
-ASensorManager_getDefaultSensor
-ASensorManager_getInstance
-ASensorManager_getSensorList
-ASensor_getMinDelay
-ASensor_getName
-ASensor_getResolution
-ASensor_getType
-ASensor_getVendor
-AStorageManager_delete
-AStorageManager_getMountedObbPath
-AStorageManager_isObbMounted
-AStorageManager_mountObb
-AStorageManager_new
-AStorageManager_unmountObb
-__FINI_ARRAY__
-__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libandroid.so.variables.txt b/ndk/platforms/android-9/arch-x86/symbols/libandroid.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libandroid.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libc.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libc.so.functions.txt
similarity index 93%
rename from ndk/platforms/android-9/arch-x86/symbols/libc.so.txt
rename to ndk/platforms/android-9/arch-x86/symbols/libc.so.functions.txt
index 6479e95..121dc51 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libc.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/libc.so.functions.txt
@@ -939,56 +939,3 @@
 write
 writev
 wscanf
-_C_ctype_
-_C_tolower_
-_C_toupper_
-__FINI_ARRAY__
-__INIT_ARRAY__
-__atexit
-__atexit_invalid
-__bionic_brk
-__evOptMonoTime
-__isthreaded
-__libc_malloc_default_dispatch
-__libc_malloc_dispatch
-__p_cert_syms
-__p_class_syms
-__p_default_section_syms
-__p_key_syms
-__p_rcode_syms
-__p_type_syms
-__p_update_section_syms
-__page_shift
-__page_size
-__progname
-__rand48_add
-__rand48_mult
-__rand48_seed
-__sF
-__sFext
-__sdidinit
-__sglue
-__stack_chk_guard
-__system_property_area__
-_ctype_
-_nres
-_ns_flagdata
-_rand48_add
-_rand48_mult
-_rand48_seed
-_res_opcodes
-_tolower_tab_
-_toupper_tab_
-daylight
-environ
-h_errlist
-h_nerr
-optarg
-opterr
-optind
-optopt
-optreset
-sys_siglist
-sys_signame
-timezone
-tzname
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libc.so.variables.txt b/ndk/platforms/android-9/arch-x86/symbols/libc.so.variables.txt
new file mode 100644
index 0000000..ce5ef63
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libc.so.variables.txt
@@ -0,0 +1,51 @@
+_C_ctype_
+_C_tolower_
+_C_toupper_
+__atexit
+__atexit_invalid
+__bionic_brk
+__evOptMonoTime
+__isthreaded
+__libc_malloc_default_dispatch
+__libc_malloc_dispatch
+__p_cert_syms
+__p_class_syms
+__p_default_section_syms
+__p_key_syms
+__p_rcode_syms
+__p_type_syms
+__p_update_section_syms
+__page_shift
+__page_size
+__progname
+__rand48_add
+__rand48_mult
+__rand48_seed
+__sF
+__sFext
+__sdidinit
+__sglue
+__stack_chk_guard
+__system_property_area__
+_ctype_
+_nres
+_ns_flagdata
+_rand48_add
+_rand48_mult
+_rand48_seed
+_res_opcodes
+_tolower_tab_
+_toupper_tab_
+daylight
+environ
+h_errlist
+h_nerr
+optarg
+opterr
+optind
+optopt
+optreset
+sys_siglist
+sys_signame
+timezone
+tzname
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libdl.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libdl.so.functions.txt
similarity index 63%
rename from ndk/platforms/android-9/arch-x86/symbols/libdl.so.txt
rename to ndk/platforms/android-9/arch-x86/symbols/libdl.so.functions.txt
index 24de29a..0419f74 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libdl.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/libdl.so.functions.txt
@@ -4,5 +4,3 @@
 dlerror
 dlopen
 dlsym
-__FINI_ARRAY__
-__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libdl.so.variables.txt b/ndk/platforms/android-9/arch-x86/symbols/libdl.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libdl.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.functions.txt
similarity index 70%
copy from ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.txt
copy to ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.functions.txt
index 9cbc8c2..61612d4 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.functions.txt
@@ -1,5 +1,3 @@
 AndroidBitmap_getInfo
 AndroidBitmap_lockPixels
 AndroidBitmap_unlockPixels
-__FINI_ARRAY__
-__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.variables.txt b/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libjnigraphics.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/liblog.so.txt b/ndk/platforms/android-9/arch-x86/symbols/liblog.so.functions.txt
similarity index 99%
rename from ndk/platforms/android-9/arch-x86/symbols/liblog.so.txt
rename to ndk/platforms/android-9/arch-x86/symbols/liblog.so.functions.txt
index 1405a81..d7a4b72 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/liblog.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/liblog.so.functions.txt
@@ -7,4 +7,3 @@
 __android_log_print
 __android_log_vprint
 __android_log_write
-
diff --git a/ndk/platforms/android-9/arch-x86/symbols/liblog.so.variables.txt b/ndk/platforms/android-9/arch-x86/symbols/liblog.so.variables.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/liblog.so.variables.txt
@@ -0,0 +1 @@
+
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libm.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libm.so.functions.txt
similarity index 95%
rename from ndk/platforms/android-9/arch-x86/symbols/libm.so.txt
rename to ndk/platforms/android-9/arch-x86/symbols/libm.so.functions.txt
index 349f00f..2899b42 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libm.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/libm.so.functions.txt
@@ -183,8 +183,3 @@
 y1f
 yn
 ynf
-__FINI_ARRAY__
-__INIT_ARRAY__
-__fe_dfl_env
-__has_sse
-signgam
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libm.so.variables.txt b/ndk/platforms/android-9/arch-x86/symbols/libm.so.variables.txt
new file mode 100644
index 0000000..6e5cdee
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libm.so.variables.txt
@@ -0,0 +1,3 @@
+__fe_dfl_env
+__has_sse
+signgam
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.functions.txt
similarity index 90%
rename from ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.txt
rename to ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.functions.txt
index 920262d..3fb5bf7 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.functions.txt
@@ -21,6 +21,3 @@
 __cxa_guard_acquire
 __cxa_guard_release
 __cxa_pure_virtual
-_ZSt7nothrow
-__FINI_ARRAY__
-__INIT_ARRAY__
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.variables.txt b/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.variables.txt
new file mode 100644
index 0000000..62e9acd
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libstdc++.so.variables.txt
@@ -0,0 +1 @@
+_ZSt7nothrow
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libz.so.txt b/ndk/platforms/android-9/arch-x86/symbols/libz.so.functions.txt
similarity index 91%
rename from ndk/platforms/android-9/arch-x86/symbols/libz.so.txt
rename to ndk/platforms/android-9/arch-x86/symbols/libz.so.functions.txt
index e35c7af..05c7c03 100644
--- a/ndk/platforms/android-9/arch-x86/symbols/libz.so.txt
+++ b/ndk/platforms/android-9/arch-x86/symbols/libz.so.functions.txt
@@ -69,8 +69,3 @@
 zError
 zlibCompileFlags
 zlibVersion
-__FINI_ARRAY__
-__INIT_ARRAY__
-deflate_copyright
-inflate_copyright
-z_errmsg
diff --git a/ndk/platforms/android-9/arch-x86/symbols/libz.so.variables.txt b/ndk/platforms/android-9/arch-x86/symbols/libz.so.variables.txt
new file mode 100644
index 0000000..6e070cd
--- /dev/null
+++ b/ndk/platforms/android-9/arch-x86/symbols/libz.so.variables.txt
@@ -0,0 +1,3 @@
+deflate_copyright
+inflate_copyright
+z_errmsg
diff --git a/samples/ActionBarCompat/Android.mk b/samples/ActionBarCompat/Android.mk
new file mode 100644
index 0000000..d9da54a
--- /dev/null
+++ b/samples/ActionBarCompat/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := ActionBarCompat
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/ActionBarCompat/AndroidManifest.xml b/samples/ActionBarCompat/AndroidManifest.xml
new file mode 100644
index 0000000..1a48274
--- /dev/null
+++ b/samples/ActionBarCompat/AndroidManifest.xml
@@ -0,0 +1,34 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.actionbarcompat"
+    android:versionCode="1"
+    android:versionName="1.0">
+
+    <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="14" />
+
+    <application android:label="@string/app_name"
+        android:icon="@drawable/ic_launcher"
+        android:theme="@style/AppTheme">
+        <activity android:name=".MainActivity" android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/samples/ActionBarCompat/_index.html b/samples/ActionBarCompat/_index.html
new file mode 100644
index 0000000..8808de1
--- /dev/null
+++ b/samples/ActionBarCompat/_index.html
@@ -0,0 +1,25 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<p>This sample shows how to use the action bar design pattern on pre-API 11 devices and the built-in
+<a href="../../../reference/android/app/ActionBar.html">ActionBar</a> on devices supporting API
+11 or greater. The example 'compatible' action bar, instantiated on pre-Android 3.0 devices,
+uses the same <a href="../../../guide/topics/resources/menu-resource.html">menu resource</a>-based
+action item definition mechanism as the new framework API, even supporting the
+<code>android:showAsAction</code> attribute to a limited extent.</p>
+
+<img alt="" src="../images/ActionBarCompat1.png" height="320" />
+<img alt="" src="../images/ActionBarCompat2.png" height="320" />
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/actionbar_shadow.9.png b/samples/ActionBarCompat/res/drawable-hdpi/actionbar_shadow.9.png
new file mode 100644
index 0000000..3c80a3f
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-hdpi/actionbar_shadow.9.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_action_refresh.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_action_refresh.png
new file mode 100644
index 0000000..efe99e0
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-hdpi/ic_action_refresh.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_action_search.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_action_search.png
new file mode 100644
index 0000000..f6719d2
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-hdpi/ic_action_search.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_action_share.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_action_share.png
new file mode 100644
index 0000000..7d0b872
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-hdpi/ic_action_share.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_home.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_home.png
new file mode 100644
index 0000000..7e52ff5
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-hdpi/ic_home.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_launcher.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_launcher.png
new file mode 100755
index 0000000..e4b0492
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-hdpi/ic_menu_share.png b/samples/ActionBarCompat/res/drawable-hdpi/ic_menu_share.png
new file mode 100755
index 0000000..a78bf7a
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-hdpi/ic_menu_share.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/actionbar_shadow.9.png b/samples/ActionBarCompat/res/drawable-mdpi/actionbar_shadow.9.png
new file mode 100644
index 0000000..cae1778
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-mdpi/actionbar_shadow.9.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_action_refresh.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_action_refresh.png
new file mode 100644
index 0000000..a85eee3
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-mdpi/ic_action_refresh.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_action_search.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_action_search.png
new file mode 100755
index 0000000..45d2398
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-mdpi/ic_action_search.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_action_share.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_action_share.png
new file mode 100644
index 0000000..26a39bd
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-mdpi/ic_action_share.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_home.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_home.png
new file mode 100644
index 0000000..949b4aa
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-mdpi/ic_home.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_launcher.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_launcher.png
new file mode 100755
index 0000000..78d0e29
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-mdpi/ic_menu_share.png b/samples/ActionBarCompat/res/drawable-mdpi/ic_menu_share.png
new file mode 100755
index 0000000..3329b6b
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-mdpi/ic_menu_share.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/actionbar_shadow.9.png b/samples/ActionBarCompat/res/drawable-xhdpi/actionbar_shadow.9.png
new file mode 100644
index 0000000..30778e3
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-xhdpi/actionbar_shadow.9.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_refresh.png b/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_refresh.png
new file mode 100644
index 0000000..6ce9376
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_refresh.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_search.png b/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_search.png
new file mode 100644
index 0000000..f89c4e9
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_search.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_share.png b/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_share.png
new file mode 100644
index 0000000..47b27d1
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-xhdpi/ic_action_share.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/ic_home.png b/samples/ActionBarCompat/res/drawable-xhdpi/ic_home.png
new file mode 100644
index 0000000..03eb53d
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-xhdpi/ic_home.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable-xhdpi/ic_launcher.png b/samples/ActionBarCompat/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..485f7be
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/ActionBarCompat/res/drawable/actionbar_compat_item.xml b/samples/ActionBarCompat/res/drawable/actionbar_compat_item.xml
new file mode 100644
index 0000000..4b3960c
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable/actionbar_compat_item.xml
@@ -0,0 +1,23 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@drawable/actionbar_compat_item_pressed"
+        android:state_pressed="true" />
+    <item android:drawable="@drawable/actionbar_compat_item_focused"
+        android:state_focused="true" />
+    <item android:drawable="@android:color/transparent" />
+</selector>
diff --git a/samples/ActionBarCompat/res/drawable/actionbar_compat_item_focused.xml b/samples/ActionBarCompat/res/drawable/actionbar_compat_item_focused.xml
new file mode 100644
index 0000000..04811d3
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable/actionbar_compat_item_focused.xml
@@ -0,0 +1,19 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#ef7000" />
+</shape>
diff --git a/samples/ActionBarCompat/res/drawable/actionbar_compat_item_pressed.xml b/samples/ActionBarCompat/res/drawable/actionbar_compat_item_pressed.xml
new file mode 100644
index 0000000..72ff4b4
--- /dev/null
+++ b/samples/ActionBarCompat/res/drawable/actionbar_compat_item_pressed.xml
@@ -0,0 +1,19 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+    <solid android:color="#eda700" />
+</shape>
diff --git a/samples/ActionBarCompat/res/layout-v11/actionbar_indeterminate_progress.xml b/samples/ActionBarCompat/res/layout-v11/actionbar_indeterminate_progress.xml
new file mode 100644
index 0000000..c05750e
--- /dev/null
+++ b/samples/ActionBarCompat/res/layout-v11/actionbar_indeterminate_progress.xml
@@ -0,0 +1,27 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:gravity="center">
+    <ProgressBar android:layout_width="32dp"
+        android:layout_height="32dp"
+        android:layout_marginLeft="12dp"
+        android:layout_marginRight="12dp"
+        android:layout_gravity="center"
+        style="?android:attr/indeterminateProgressStyle" />
+</FrameLayout>
diff --git a/samples/ActionBarCompat/res/layout/actionbar_compat.xml b/samples/ActionBarCompat/res/layout/actionbar_compat.xml
new file mode 100644
index 0000000..ae6c44b
--- /dev/null
+++ b/samples/ActionBarCompat/res/layout/actionbar_compat.xml
@@ -0,0 +1,21 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@id/actionbar_compat"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:orientation="horizontal" />
diff --git a/samples/ActionBarCompat/res/layout/main.xml b/samples/ActionBarCompat/res/layout/main.xml
new file mode 100644
index 0000000..a58a346
--- /dev/null
+++ b/samples/ActionBarCompat/res/layout/main.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    <Button android:id="@+id/toggle_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center"
+        android:text="@string/toggle_title" />
+</FrameLayout>
diff --git a/samples/ActionBarCompat/res/menu/main.xml b/samples/ActionBarCompat/res/menu/main.xml
new file mode 100644
index 0000000..a306a3c
--- /dev/null
+++ b/samples/ActionBarCompat/res/menu/main.xml
@@ -0,0 +1,34 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/menu_refresh"
+        android:title="@string/menu_refresh"
+        android:icon="@drawable/ic_action_refresh"
+        android:orderInCategory="1"
+        android:showAsAction="always" />
+    <item android:id="@+id/menu_search"
+        android:title="@string/menu_search"
+        android:icon="@drawable/ic_action_search"
+        android:orderInCategory="0"
+        android:showAsAction="always" />
+
+    <item android:id="@+id/menu_share"
+        android:title="@string/menu_share"
+        android:icon="@drawable/ic_menu_share"
+        android:orderInCategory="1"
+        android:showAsAction="never" />
+</menu>
diff --git a/samples/ActionBarCompat/res/values-v11/styles.xml b/samples/ActionBarCompat/res/values-v11/styles.xml
new file mode 100644
index 0000000..dc1aa7c
--- /dev/null
+++ b/samples/ActionBarCompat/res/values-v11/styles.xml
@@ -0,0 +1,34 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <style name="AppTheme" parent="android:style/Theme.Holo.Light">
+        <item name="android:actionBarStyle">@style/ActionBar</item>
+        <item name="android:windowContentOverlay">@drawable/actionbar_shadow</item>
+    </style>
+
+    <style name="ActionBar" parent="android:style/Widget.Holo.Light.ActionBar">
+        <item name="android:background">#eee</item>
+        <item name="android:titleTextStyle">@style/ActionBarTitle</item>
+        <item name="android:icon">@drawable/ic_home</item>
+    </style>
+
+    <style name="ActionBarTitle">
+        <item name="android:textColor">@color/actionbar_title_color</item>
+    </style>
+
+</resources>
diff --git a/samples/ActionBarCompat/res/values-v13/styles.xml b/samples/ActionBarCompat/res/values-v13/styles.xml
new file mode 100644
index 0000000..8a042b4
--- /dev/null
+++ b/samples/ActionBarCompat/res/values-v13/styles.xml
@@ -0,0 +1,23 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <style name="ActionBarTitle" parent="android:style/TextAppearance.Holo.Widget.ActionBar.Title">
+        <item name="android:textColor">@color/actionbar_title_color</item>
+    </style>
+
+</resources>
diff --git a/samples/ActionBarCompat/res/values/attrs.xml b/samples/ActionBarCompat/res/values/attrs.xml
new file mode 100644
index 0000000..c59822c
--- /dev/null
+++ b/samples/ActionBarCompat/res/values/attrs.xml
@@ -0,0 +1,31 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <declare-styleable name="AppTheme">
+        <attr name="actionbarCompatTitleStyle" format="reference" />
+        <attr name="actionbarCompatItemStyle" format="reference" />
+        <attr name="actionbarCompatItemHomeStyle" format="reference" />
+        <attr name="actionbarCompatProgressIndicatorStyle" format="reference" />
+    </declare-styleable>
+
+    <declare-styleable name="BezelImageView">
+        <attr name="maskDrawable" format="reference" />
+        <attr name="borderDrawable" format="reference" />
+    </declare-styleable>
+
+</resources>
diff --git a/samples/ActionBarCompat/res/values/colors.xml b/samples/ActionBarCompat/res/values/colors.xml
new file mode 100644
index 0000000..4edc6d6
--- /dev/null
+++ b/samples/ActionBarCompat/res/values/colors.xml
@@ -0,0 +1,19 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <color name="actionbar_title_color">#224894</color>
+</resources>
diff --git a/samples/ActionBarCompat/res/values/dimens.xml b/samples/ActionBarCompat/res/values/dimens.xml
new file mode 100644
index 0000000..67c8436
--- /dev/null
+++ b/samples/ActionBarCompat/res/values/dimens.xml
@@ -0,0 +1,21 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <dimen name="actionbar_compat_height">48dp</dimen>
+    <dimen name="actionbar_compat_button_width">48dp</dimen>
+    <dimen name="actionbar_compat_button_home_width">56dp</dimen>
+</resources>
diff --git a/samples/ActionBarCompat/res/values/ids.xml b/samples/ActionBarCompat/res/values/ids.xml
new file mode 100644
index 0000000..e0a4745
--- /dev/null
+++ b/samples/ActionBarCompat/res/values/ids.xml
@@ -0,0 +1,23 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <item type="id" name="actionbar_compat" />
+    <item type="id" name="actionbar_compat_title" />
+    <item type="id" name="actionbar_compat_item_refresh_progress" />
+    <item type="id" name="actionbar_compat_item_refresh" />
+    <item type="id" name="menu_refresh" />
+</resources>
diff --git a/samples/ActionBarCompat/res/values/strings.xml b/samples/ActionBarCompat/res/values/strings.xml
new file mode 100644
index 0000000..234aa78
--- /dev/null
+++ b/samples/ActionBarCompat/res/values/strings.xml
@@ -0,0 +1,25 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+    <string name="app_name">Action Bar Demo</string>
+    <string name="alternate_title">An alternate title that is long</string>
+    <string name="toggle_title">Toggle title</string>
+
+    <string name="menu_refresh">Refresh</string>
+    <string name="menu_search">Search</string>
+    <string name="menu_share">Share</string>
+</resources>
diff --git a/samples/ActionBarCompat/res/values/styles.xml b/samples/ActionBarCompat/res/values/styles.xml
new file mode 100644
index 0000000..5d0c029
--- /dev/null
+++ b/samples/ActionBarCompat/res/values/styles.xml
@@ -0,0 +1,66 @@
+<!--
+  Copyright 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<resources>
+
+    <style name="AppTheme" parent="android:style/Theme.Light">
+        <item name="android:windowTitleSize">@dimen/actionbar_compat_height</item>
+        <item name="android:windowTitleBackgroundStyle">@style/ActionBarCompat</item>
+        <item name="android:windowContentOverlay">@drawable/actionbar_shadow</item>
+
+        <!-- for programmatic instantiation -->
+        <item name="actionbarCompatTitleStyle">@style/ActionBarCompatTitle</item>
+        <item name="actionbarCompatItemStyle">@style/ActionBarCompatItem</item>
+        <item name="actionbarCompatItemHomeStyle">@style/ActionBarCompatHomeItem</item>
+        <item name="actionbarCompatProgressIndicatorStyle">@style/ActionBarCompatProgressIndicator</item>
+    </style>
+
+    <style name="ActionBarCompat">
+        <item name="android:background">#eee</item>
+    </style>
+
+    <style name="ActionBarCompatItemBase">
+        <!-- layout_width/height must be set in code -->
+        <item name="android:scaleType">center</item>
+        <item name="android:background">@drawable/actionbar_compat_item</item>
+    </style>
+
+    <style name="ActionBarCompatProgressIndicator" parent="android:style/Widget.ProgressBar.Large">
+        <item name="android:indeterminate">true</item>
+    </style>
+
+    <style name="ActionBarCompatTitleBase">
+        <item name="android:id">@id/actionbar_compat_title</item>
+        <!-- layout_width/height/weight must be set in code -->
+        <item name="android:gravity">center_vertical</item>
+        <item name="android:textSize">18sp</item>
+        <item name="android:paddingLeft">6dp</item>
+        <item name="android:paddingRight">6dp</item>
+        <item name="android:singleLine">true</item>
+        <item name="android:ellipsize">marquee</item>
+    </style>
+
+    <style name="ActionBarCompatTitle" parent="style/ActionBarCompatTitleBase">
+        <item name="android:textColor">@color/actionbar_title_color</item>
+    </style>
+
+    <style name="ActionBarCompatItem" parent="style/ActionBarCompatItemBase">
+    </style>
+
+    <style name="ActionBarCompatHomeItem" parent="style/ActionBarCompatItemBase">
+    </style>
+
+</resources>
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarActivity.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarActivity.java
new file mode 100644
index 0000000..251e411
--- /dev/null
+++ b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarActivity.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.actionbarcompat;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+
+/**
+ * A base activity that defers common functionality across app activities to an {@link
+ * ActionBarHelper}.
+ *
+ * NOTE: dynamically marking menu items as invisible/visible is not currently supported.
+ *
+ * NOTE: this may used with the Android Compatibility Package by extending
+ * android.support.v4.app.FragmentActivity instead of {@link Activity}.
+ */
+public abstract class ActionBarActivity extends Activity {
+    final ActionBarHelper mActionBarHelper = ActionBarHelper.createInstance(this);
+
+    /**
+     * Returns the {@link ActionBarHelper} for this activity.
+     */
+    protected ActionBarHelper getActionBarHelper() {
+        return mActionBarHelper;
+    }
+
+    /**{@inheritDoc}*/
+    @Override
+    public MenuInflater getMenuInflater() {
+        return mActionBarHelper.getMenuInflater(super.getMenuInflater());
+    }
+
+    /**{@inheritDoc}*/
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mActionBarHelper.onCreate(savedInstanceState);
+    }
+
+    /**{@inheritDoc}*/
+    @Override
+    protected void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        mActionBarHelper.onPostCreate(savedInstanceState);
+    }
+
+    /**
+     * Base action bar-aware implementation for
+     * {@link Activity#onCreateOptionsMenu(android.view.Menu)}.
+     *
+     * Note: marking menu items as invisible/visible is not currently supported.
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        boolean retValue = false;
+        retValue |= mActionBarHelper.onCreateOptionsMenu(menu);
+        retValue |= super.onCreateOptionsMenu(menu);
+        return retValue;
+    }
+
+    /**{@inheritDoc}*/
+    @Override
+    protected void onTitleChanged(CharSequence title, int color) {
+        mActionBarHelper.onTitleChanged(title, color);
+        super.onTitleChanged(title, color);
+    }
+}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelper.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelper.java
new file mode 100644
index 0000000..075f993
--- /dev/null
+++ b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelper.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.actionbarcompat;
+
+import android.app.Activity;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+
+/**
+ * An abstract class that handles some common action bar-related functionality in the app. This
+ * class provides functionality useful for both phones and tablets, and does not require any Android
+ * 3.0-specific features, although it uses them if available.
+ *
+ * Two implementations of this class are {@link ActionBarHelperBase} for a pre-Honeycomb version of
+ * the action bar, and {@link ActionBarHelperHoneycomb}, which uses the built-in ActionBar features
+ * in Android 3.0 and later.
+ */
+public abstract class ActionBarHelper {
+    protected Activity mActivity;
+
+    /**
+     * Factory method for creating {@link ActionBarHelper} objects for a
+     * given activity. Depending on which device the app is running, either a basic helper or
+     * Honeycomb-specific helper will be returned.
+     */
+    public static ActionBarHelper createInstance(Activity activity) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            return new ActionBarHelperICS(activity);
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+            return new ActionBarHelperHoneycomb(activity);
+        } else {
+            return new ActionBarHelperBase(activity);
+        }
+    }
+
+    protected ActionBarHelper(Activity activity) {
+        mActivity = activity;
+    }
+
+    /**
+     * Action bar helper code to be run in {@link Activity#onCreate(android.os.Bundle)}.
+     */
+    public void onCreate(Bundle savedInstanceState) {
+    }
+
+    /**
+     * Action bar helper code to be run in {@link Activity#onPostCreate(android.os.Bundle)}.
+     */
+    public void onPostCreate(Bundle savedInstanceState) {
+    }
+
+    /**
+     * Action bar helper code to be run in {@link Activity#onCreateOptionsMenu(android.view.Menu)}.
+     *
+     * NOTE: Setting the visibility of menu items in <em>menu</em> is not currently supported.
+     */
+    public boolean onCreateOptionsMenu(Menu menu) {
+        return true;
+    }
+
+    /**
+     * Action bar helper code to be run in {@link Activity#onTitleChanged(CharSequence, int)}.
+     */
+    protected void onTitleChanged(CharSequence title, int color) {
+    }
+
+    /**
+     * Sets the indeterminate loading state of the item with ID {@link R.id.menu_refresh}.
+     * (where the item ID was menu_refresh).
+     */
+    public abstract void setRefreshActionItemState(boolean refreshing);
+
+    /**
+     * Returns a {@link MenuInflater} for use when inflating menus. The implementation of this
+     * method in {@link ActionBarHelperBase} returns a wrapped menu inflater that can read
+     * action bar metadata from a menu resource pre-Honeycomb.
+     */
+    public MenuInflater getMenuInflater(MenuInflater superMenuInflater) {
+        return superMenuInflater;
+    }
+}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperBase.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperBase.java
new file mode 100644
index 0000000..f70b54a
--- /dev/null
+++ b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperBase.java
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.actionbarcompat;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.XmlResourceParser;
+import android.os.Bundle;
+import android.view.InflateException;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A class that implements the action bar pattern for pre-Honeycomb devices.
+ */
+public class ActionBarHelperBase extends ActionBarHelper {
+    private static final String MENU_RES_NAMESPACE = "http://schemas.android.com/apk/res/android";
+    private static final String MENU_ATTR_ID = "id";
+    private static final String MENU_ATTR_SHOW_AS_ACTION = "showAsAction";
+
+    protected Set<Integer> mActionItemIds = new HashSet<Integer>();
+
+    protected ActionBarHelperBase(Activity activity) {
+        super(activity);
+    }
+
+    /**{@inheritDoc}*/
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
+    }
+
+    /**{@inheritDoc}*/
+    @Override
+    public void onPostCreate(Bundle savedInstanceState) {
+        mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
+                R.layout.actionbar_compat);
+        setupActionBar();
+
+        SimpleMenu menu = new SimpleMenu(mActivity);
+        mActivity.onCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, menu);
+        mActivity.onPrepareOptionsMenu(menu);
+        for (int i = 0; i < menu.size(); i++) {
+            MenuItem item = menu.getItem(i);
+            if (mActionItemIds.contains(item.getItemId())) {
+                addActionItemCompatFromMenuItem(item);
+            }
+        }
+    }
+
+    /**
+     * Sets up the compatibility action bar with the given title.
+     */
+    private void setupActionBar() {
+        final ViewGroup actionBarCompat = getActionBarCompat();
+        if (actionBarCompat == null) {
+            return;
+        }
+
+        LinearLayout.LayoutParams springLayoutParams = new LinearLayout.LayoutParams(
+                0, ViewGroup.LayoutParams.FILL_PARENT);
+        springLayoutParams.weight = 1;
+
+        // Add Home button
+        SimpleMenu tempMenu = new SimpleMenu(mActivity);
+        SimpleMenuItem homeItem = new SimpleMenuItem(
+                tempMenu, android.R.id.home, 0, mActivity.getString(R.string.app_name));
+        homeItem.setIcon(R.drawable.ic_home);
+        addActionItemCompatFromMenuItem(homeItem);
+
+        // Add title text
+        TextView titleText = new TextView(mActivity, null, R.attr.actionbarCompatTitleStyle);
+        titleText.setLayoutParams(springLayoutParams);
+        titleText.setText(mActivity.getTitle());
+        actionBarCompat.addView(titleText);
+    }
+
+    /**{@inheritDoc}*/
+    @Override
+    public void setRefreshActionItemState(boolean refreshing) {
+        View refreshButton = mActivity.findViewById(R.id.actionbar_compat_item_refresh);
+        View refreshIndicator = mActivity.findViewById(
+                R.id.actionbar_compat_item_refresh_progress);
+
+        if (refreshButton != null) {
+            refreshButton.setVisibility(refreshing ? View.GONE : View.VISIBLE);
+        }
+        if (refreshIndicator != null) {
+            refreshIndicator.setVisibility(refreshing ? View.VISIBLE : View.GONE);
+        }
+    }
+
+    /**
+     * Action bar helper code to be run in {@link Activity#onCreateOptionsMenu(android.view.Menu)}.
+     *
+     * NOTE: This code will mark on-screen menu items as invisible.
+     */
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        // Hides on-screen action items from the options menu.
+        for (Integer id : mActionItemIds) {
+            menu.findItem(id).setVisible(false);
+        }
+        return true;
+    }
+
+    /**{@inheritDoc}*/
+    @Override
+    protected void onTitleChanged(CharSequence title, int color) {
+        TextView titleView = (TextView) mActivity.findViewById(R.id.actionbar_compat_title);
+        if (titleView != null) {
+            titleView.setText(title);
+        }
+    }
+
+    /**
+     * Returns a {@link android.view.MenuInflater} that can read action bar metadata on
+     * pre-Honeycomb devices.
+     */
+    public MenuInflater getMenuInflater(MenuInflater superMenuInflater) {
+        return new WrappedMenuInflater(mActivity, superMenuInflater);
+    }
+
+    /**
+     * Returns the {@link android.view.ViewGroup} for the action bar on phones (compatibility action
+     * bar). Can return null, and will return null on Honeycomb.
+     */
+    private ViewGroup getActionBarCompat() {
+        return (ViewGroup) mActivity.findViewById(R.id.actionbar_compat);
+    }
+
+    /**
+     * Adds an action button to the compatibility action bar, using menu information from a {@link
+     * android.view.MenuItem}. If the menu item ID is <code>menu_refresh</code>, the menu item's
+     * state can be changed to show a loading spinner using
+     * {@link com.example.android.actionbarcompat.ActionBarHelperBase#setRefreshActionItemState(boolean)}.
+     */
+    private View addActionItemCompatFromMenuItem(final MenuItem item) {
+        final int itemId = item.getItemId();
+
+        final ViewGroup actionBar = getActionBarCompat();
+        if (actionBar == null) {
+            return null;
+        }
+
+        // Create the button
+        ImageButton actionButton = new ImageButton(mActivity, null,
+                itemId == android.R.id.home
+                        ? R.attr.actionbarCompatItemHomeStyle
+                        : R.attr.actionbarCompatItemStyle);
+        actionButton.setLayoutParams(new ViewGroup.LayoutParams(
+                (int) mActivity.getResources().getDimension(
+                        itemId == android.R.id.home
+                                ? R.dimen.actionbar_compat_button_home_width
+                                : R.dimen.actionbar_compat_button_width),
+                ViewGroup.LayoutParams.FILL_PARENT));
+        if (itemId == R.id.menu_refresh) {
+            actionButton.setId(R.id.actionbar_compat_item_refresh);
+        }
+        actionButton.setImageDrawable(item.getIcon());
+        actionButton.setScaleType(ImageView.ScaleType.CENTER);
+        actionButton.setContentDescription(item.getTitle());
+        actionButton.setOnClickListener(new View.OnClickListener() {
+            public void onClick(View view) {
+                mActivity.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);
+            }
+        });
+
+        actionBar.addView(actionButton);
+
+        if (item.getItemId() == R.id.menu_refresh) {
+            // Refresh buttons should be stateful, and allow for indeterminate progress indicators,
+            // so add those.
+            ProgressBar indicator = new ProgressBar(mActivity, null,
+                    R.attr.actionbarCompatProgressIndicatorStyle);
+
+            final int buttonWidth = mActivity.getResources().getDimensionPixelSize(
+                    R.dimen.actionbar_compat_button_width);
+            final int buttonHeight = mActivity.getResources().getDimensionPixelSize(
+                    R.dimen.actionbar_compat_height);
+            final int progressIndicatorWidth = buttonWidth / 2;
+
+            LinearLayout.LayoutParams indicatorLayoutParams = new LinearLayout.LayoutParams(
+                    progressIndicatorWidth, progressIndicatorWidth);
+            indicatorLayoutParams.setMargins(
+                    (buttonWidth - progressIndicatorWidth) / 2,
+                    (buttonHeight - progressIndicatorWidth) / 2,
+                    (buttonWidth - progressIndicatorWidth) / 2,
+                    0);
+            indicator.setLayoutParams(indicatorLayoutParams);
+            indicator.setVisibility(View.GONE);
+            indicator.setId(R.id.actionbar_compat_item_refresh_progress);
+            actionBar.addView(indicator);
+        }
+
+        return actionButton;
+    }
+
+    /**
+     * A {@link android.view.MenuInflater} that reads action bar metadata.
+     */
+    private class WrappedMenuInflater extends MenuInflater {
+        MenuInflater mInflater;
+
+        public WrappedMenuInflater(Context context, MenuInflater inflater) {
+            super(context);
+            mInflater = inflater;
+        }
+
+        @Override
+        public void inflate(int menuRes, Menu menu) {
+            loadActionBarMetadata(menuRes);
+            mInflater.inflate(menuRes, menu);
+        }
+
+        /**
+         * Loads action bar metadata from a menu resource, storing a list of menu item IDs that
+         * should be shown on-screen (i.e. those with showAsAction set to always or ifRoom).
+         * @param menuResId
+         */
+        private void loadActionBarMetadata(int menuResId) {
+            XmlResourceParser parser = null;
+            try {
+                parser = mActivity.getResources().getXml(menuResId);
+
+                int eventType = parser.getEventType();
+                int itemId;
+                int showAsAction;
+
+                boolean eof = false;
+                while (!eof) {
+                    switch (eventType) {
+                        case XmlPullParser.START_TAG:
+                            if (!parser.getName().equals("item")) {
+                                break;
+                            }
+
+                            itemId = parser.getAttributeResourceValue(MENU_RES_NAMESPACE,
+                                    MENU_ATTR_ID, 0);
+                            if (itemId == 0) {
+                                break;
+                            }
+
+                            showAsAction = parser.getAttributeIntValue(MENU_RES_NAMESPACE,
+                                    MENU_ATTR_SHOW_AS_ACTION, -1);
+                            if (showAsAction == MenuItem.SHOW_AS_ACTION_ALWAYS ||
+                                    showAsAction == MenuItem.SHOW_AS_ACTION_IF_ROOM) {
+                                mActionItemIds.add(itemId);
+                            }
+                            break;
+
+                        case XmlPullParser.END_DOCUMENT:
+                            eof = true;
+                            break;
+                    }
+
+                    eventType = parser.next();
+                }
+            } catch (XmlPullParserException e) {
+                throw new InflateException("Error inflating menu XML", e);
+            } catch (IOException e) {
+                throw new InflateException("Error inflating menu XML", e);
+            } finally {
+                if (parser != null) {
+                    parser.close();
+                }
+            }
+        }
+
+    }
+}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperHoneycomb.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperHoneycomb.java
new file mode 100644
index 0000000..16fba69
--- /dev/null
+++ b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperHoneycomb.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.actionbarcompat;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+
+/**
+ * An extension of {@link ActionBarHelper} that provides Android 3.0-specific functionality for
+ * Honeycomb tablets. It thus requires API level 11.
+ */
+public class ActionBarHelperHoneycomb extends ActionBarHelper {
+    private Menu mOptionsMenu;
+    private View mRefreshIndeterminateProgressView = null;
+
+    protected ActionBarHelperHoneycomb(Activity activity) {
+        super(activity);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        mOptionsMenu = menu;
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public void setRefreshActionItemState(boolean refreshing) {
+        // On Honeycomb, we can set the state of the refresh button by giving it a custom
+        // action view.
+        if (mOptionsMenu == null) {
+            return;
+        }
+
+        final MenuItem refreshItem = mOptionsMenu.findItem(R.id.menu_refresh);
+        if (refreshItem != null) {
+            if (refreshing) {
+                if (mRefreshIndeterminateProgressView == null) {
+                    LayoutInflater inflater = (LayoutInflater)
+                            getActionBarThemedContext().getSystemService(
+                                    Context.LAYOUT_INFLATER_SERVICE);
+                    mRefreshIndeterminateProgressView = inflater.inflate(
+                            R.layout.actionbar_indeterminate_progress, null);
+                }
+
+                refreshItem.setActionView(mRefreshIndeterminateProgressView);
+            } else {
+                refreshItem.setActionView(null);
+            }
+        }
+    }
+
+    /**
+     * Returns a {@link Context} suitable for inflating layouts for the action bar. The
+     * implementation for this method in {@link ActionBarHelperICS} asks the action bar for a
+     * themed context.
+     */
+    protected Context getActionBarThemedContext() {
+        return mActivity;
+    }
+}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperICS.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperICS.java
new file mode 100644
index 0000000..d2239db
--- /dev/null
+++ b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/ActionBarHelperICS.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.actionbarcompat;
+
+import android.app.Activity;
+import android.content.Context;
+import android.view.Menu;
+import android.view.MenuItem;
+
+/**
+ * An extension of {@link com.example.android.actionbarcompat.ActionBarHelper} that provides Android
+ * 4.0-specific functionality for IceCreamSandwich devices. It thus requires API level 14.
+ */
+public class ActionBarHelperICS extends ActionBarHelperHoneycomb {
+    protected ActionBarHelperICS(Activity activity) {
+        super(activity);
+    }
+
+    @Override
+    protected Context getActionBarThemedContext() {
+        return mActivity.getActionBar().getThemedContext();
+    }
+}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/MainActivity.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/MainActivity.java
new file mode 100644
index 0000000..facf1ae
--- /dev/null
+++ b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/MainActivity.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.actionbarcompat;
+
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Toast;
+
+public class MainActivity extends ActionBarActivity {
+    private boolean mAlternateTitle = false;
+
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+
+        findViewById(R.id.toggle_title).setOnClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View view) {
+                if (mAlternateTitle) {
+                    setTitle(R.string.app_name);
+                } else {
+                    setTitle(R.string.alternate_title);
+                }
+                mAlternateTitle = !mAlternateTitle;
+            }
+        });
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater menuInflater = getMenuInflater();
+        menuInflater.inflate(R.menu.main, menu);
+
+        // Calling super after populating the menu is necessary here to ensure that the
+        // action bar helpers have a chance to handle this event.
+        return super.onCreateOptionsMenu(menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case android.R.id.home:
+                Toast.makeText(this, "Tapped home", Toast.LENGTH_SHORT).show();
+                break;
+
+            case R.id.menu_refresh:
+                Toast.makeText(this, "Fake refreshing...", Toast.LENGTH_SHORT).show();
+                getActionBarHelper().setRefreshActionItemState(true);
+                getWindow().getDecorView().postDelayed(
+                        new Runnable() {
+                            @Override
+                            public void run() {
+                                getActionBarHelper().setRefreshActionItemState(false);
+                            }
+                        }, 1000);
+                break;
+
+            case R.id.menu_search:
+                Toast.makeText(this, "Tapped search", Toast.LENGTH_SHORT).show();
+                break;
+
+            case R.id.menu_share:
+                Toast.makeText(this, "Tapped share", Toast.LENGTH_SHORT).show();
+                break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenu.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenu.java
new file mode 100644
index 0000000..8b694d0
--- /dev/null
+++ b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenu.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.actionbarcompat;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.SubMenu;
+
+import java.util.ArrayList;
+
+/**
+ * A <em>really</em> dumb implementation of the {@link android.view.Menu} interface, that's only
+ * useful for our actionbar-compat purposes. See
+ * <code>com.android.internal.view.menu.MenuBuilder</code> in AOSP for a more complete
+ * implementation.
+ */
+public class SimpleMenu implements Menu {
+
+    private Context mContext;
+    private Resources mResources;
+
+    private ArrayList<SimpleMenuItem> mItems;
+
+    public SimpleMenu(Context context) {
+        mContext = context;
+        mResources = context.getResources();
+        mItems = new ArrayList<SimpleMenuItem>();
+    }
+
+    public Context getContext() {
+        return mContext;
+    }
+
+    public Resources getResources() {
+        return mResources;
+    }
+
+    public MenuItem add(CharSequence title) {
+        return addInternal(0, 0, title);
+    }
+
+    public MenuItem add(int titleRes) {
+        return addInternal(0, 0, mResources.getString(titleRes));
+    }
+
+    public MenuItem add(int groupId, int itemId, int order, CharSequence title) {
+        return addInternal(itemId, order, title);
+    }
+
+    public MenuItem add(int groupId, int itemId, int order, int titleRes) {
+        return addInternal(itemId, order, mResources.getString(titleRes));
+    }
+
+    /**
+     * Adds an item to the menu.  The other add methods funnel to this.
+     */
+    private MenuItem addInternal(int itemId, int order, CharSequence title) {
+        final SimpleMenuItem item = new SimpleMenuItem(this, itemId, order, title);
+        mItems.add(findInsertIndex(mItems, order), item);
+        return item;
+    }
+
+    private static int findInsertIndex(ArrayList<? extends MenuItem> items, int order) {
+        for (int i = items.size() - 1; i >= 0; i--) {
+            MenuItem item = items.get(i);
+            if (item.getOrder() <= order) {
+                return i + 1;
+            }
+        }
+
+        return 0;
+    }
+
+    public int findItemIndex(int id) {
+        final int size = size();
+
+        for (int i = 0; i < size; i++) {
+            SimpleMenuItem item = mItems.get(i);
+            if (item.getItemId() == id) {
+                return i;
+            }
+        }
+
+        return -1;
+    }
+
+    public void removeItem(int itemId) {
+        removeItemAtInt(findItemIndex(itemId));
+    }
+
+    private void removeItemAtInt(int index) {
+        if ((index < 0) || (index >= mItems.size())) {
+            return;
+        }
+        mItems.remove(index);
+    }
+
+    public void clear() {
+        mItems.clear();
+    }
+
+    public MenuItem findItem(int id) {
+        final int size = size();
+        for (int i = 0; i < size; i++) {
+            SimpleMenuItem item = mItems.get(i);
+            if (item.getItemId() == id) {
+                return item;
+            }
+        }
+
+        return null;
+    }
+
+    public int size() {
+        return mItems.size();
+    }
+
+    public MenuItem getItem(int index) {
+        return mItems.get(index);
+    }
+
+    // Unsupported operations.
+
+    public SubMenu addSubMenu(CharSequence charSequence) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public SubMenu addSubMenu(int titleRes) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public SubMenu addSubMenu(int groupId, int itemId, int order, CharSequence title) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public int addIntentOptions(int i, int i1, int i2, ComponentName componentName,
+            Intent[] intents, Intent intent, int i3, MenuItem[] menuItems) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public void removeGroup(int i) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public void setGroupCheckable(int i, boolean b, boolean b1) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public void setGroupVisible(int i, boolean b) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public void setGroupEnabled(int i, boolean b) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public boolean hasVisibleItems() {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public void close() {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public boolean performShortcut(int i, KeyEvent keyEvent, int i1) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public boolean isShortcutKey(int i, KeyEvent keyEvent) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public boolean performIdentifierAction(int i, int i1) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+
+    public void setQwertyMode(boolean b) {
+        throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
+    }
+}
diff --git a/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenuItem.java b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenuItem.java
new file mode 100644
index 0000000..425ba72
--- /dev/null
+++ b/samples/ActionBarCompat/src/com/example/android/actionbarcompat/SimpleMenuItem.java
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.actionbarcompat;
+
+import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.view.ActionProvider;
+import android.view.ContextMenu;
+import android.view.MenuItem;
+import android.view.SubMenu;
+import android.view.View;
+
+/**
+ * A <em>really</em> dumb implementation of the {@link android.view.MenuItem} interface, that's only
+ * useful for our actionbar-compat purposes. See
+ * <code>com.android.internal.view.menu.MenuItemImpl</code> in AOSP for a more complete
+ * implementation.
+ */
+public class SimpleMenuItem implements MenuItem {
+
+    private SimpleMenu mMenu;
+
+    private final int mId;
+    private final int mOrder;
+    private CharSequence mTitle;
+    private CharSequence mTitleCondensed;
+    private Drawable mIconDrawable;
+    private int mIconResId = 0;
+    private boolean mEnabled = true;
+
+    public SimpleMenuItem(SimpleMenu menu, int id, int order, CharSequence title) {
+        mMenu = menu;
+        mId = id;
+        mOrder = order;
+        mTitle = title;
+    }
+
+    public int getItemId() {
+        return mId;
+    }
+
+    public int getOrder() {
+        return mOrder;
+    }
+
+    public MenuItem setTitle(CharSequence title) {
+        mTitle = title;
+        return this;
+    }
+
+    public MenuItem setTitle(int titleRes) {
+        return setTitle(mMenu.getContext().getString(titleRes));
+    }
+
+    public CharSequence getTitle() {
+        return mTitle;
+    }
+
+    public MenuItem setTitleCondensed(CharSequence title) {
+        mTitleCondensed = title;
+        return this;
+    }
+
+    public CharSequence getTitleCondensed() {
+        return mTitleCondensed != null ? mTitleCondensed : mTitle;
+    }
+
+    public MenuItem setIcon(Drawable icon) {
+        mIconResId = 0;
+        mIconDrawable = icon;
+        return this;
+    }
+
+    public MenuItem setIcon(int iconResId) {
+        mIconDrawable = null;
+        mIconResId = iconResId;
+        return this;
+    }
+
+    public Drawable getIcon() {
+        if (mIconDrawable != null) {
+            return mIconDrawable;
+        }
+
+        if (mIconResId != 0) {
+            return mMenu.getResources().getDrawable(mIconResId);
+        }
+
+        return null;
+    }
+
+    public MenuItem setEnabled(boolean enabled) {
+        mEnabled = enabled;
+        return this;
+    }
+
+    public boolean isEnabled() {
+        return mEnabled;
+    }
+
+    // No-op operations. We use no-ops to allow inflation from menu XML.
+
+    public int getGroupId() {
+        // Noop
+        return 0;
+    }
+
+    public View getActionView() {
+        // Noop
+        return null;
+    }
+
+    public MenuItem setActionProvider(ActionProvider actionProvider) {
+        // Noop
+        return this;
+    }
+
+    public ActionProvider getActionProvider() {
+        // Noop
+        return null;
+    }
+
+    public boolean expandActionView() {
+        // Noop
+        return false;
+    }
+
+    public boolean collapseActionView() {
+        // Noop
+        return false;
+    }
+
+    public boolean isActionViewExpanded() {
+        // Noop
+        return false;
+    }
+
+    @Override
+    public MenuItem setOnActionExpandListener(OnActionExpandListener onActionExpandListener) {
+        // Noop
+        return this;
+    }
+
+    public MenuItem setIntent(Intent intent) {
+        // Noop
+        return this;
+    }
+
+    public Intent getIntent() {
+        // Noop
+        return null;
+    }
+
+    public MenuItem setShortcut(char c, char c1) {
+        // Noop
+        return this;
+    }
+
+    public MenuItem setNumericShortcut(char c) {
+        // Noop
+        return this;
+    }
+
+    public char getNumericShortcut() {
+        // Noop
+        return 0;
+    }
+
+    public MenuItem setAlphabeticShortcut(char c) {
+        // Noop
+        return this;
+    }
+
+    public char getAlphabeticShortcut() {
+        // Noop
+        return 0;
+    }
+
+    public MenuItem setCheckable(boolean b) {
+        // Noop
+        return this;
+    }
+
+    public boolean isCheckable() {
+        // Noop
+        return false;
+    }
+
+    public MenuItem setChecked(boolean b) {
+        // Noop
+        return this;
+    }
+
+    public boolean isChecked() {
+        // Noop
+        return false;
+    }
+
+    public MenuItem setVisible(boolean b) {
+        // Noop
+        return this;
+    }
+
+    public boolean isVisible() {
+        // Noop
+        return true;
+    }
+
+    public boolean hasSubMenu() {
+        // Noop
+        return false;
+    }
+
+    public SubMenu getSubMenu() {
+        // Noop
+        return null;
+    }
+
+    public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener onMenuItemClickListener) {
+        // Noop
+        return this;
+    }
+
+    public ContextMenu.ContextMenuInfo getMenuInfo() {
+        // Noop
+        return null;
+    }
+
+    public void setShowAsAction(int i) {
+        // Noop
+    }
+
+    public MenuItem setShowAsActionFlags(int i) {
+        // Noop
+        return null;
+    }
+
+    public MenuItem setActionView(View view) {
+        // Noop
+        return this;
+    }
+
+    public MenuItem setActionView(int i) {
+        // Noop
+        return this;
+    }
+}
diff --git a/samples/AndroidBeam/AndroidManifest.xml b/samples/AndroidBeam/AndroidManifest.xml
new file mode 100644
index 0000000..e01eb2d
--- /dev/null
+++ b/samples/AndroidBeam/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+        package="com.example.android.beam"
+        android:versionCode="1"
+        android:versionName="1.0">
+    <uses-permission android:name="android.permission.NFC" />
+    <uses-sdk android:minSdkVersion="14" />
+    <uses-feature android:name="android.hardware.nfc" />
+    <application android:icon="@drawable/icon" android:label="@string/app_name">
+        <activity android:name="com.example.android.beam.Beam"
+                android:label="@string/app_name"
+                android:launchMode="singleTop">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.nfc.action.NDEF_DISCOVERED" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="application/com.example.android.beam" />
+            </intent-filter>
+        </activity>
+    </application>
+</manifest>
diff --git a/samples/AndroidBeam/_index.html b/samples/AndroidBeam/_index.html
new file mode 100755
index 0000000..ad4e71a
--- /dev/null
+++ b/samples/AndroidBeam/_index.html
@@ -0,0 +1,3 @@
+<p>The Beam application demonstrates how to use the Android Beam feature introduced in API level 14. This
+application beams a simple message from one device to another when they are in close enough proximity. This
+application must be installed on two devices that have NFC capabilities, running Android 4.0 or later.</p>
diff --git a/samples/AndroidBeam/res/drawable-hdpi/icon.png b/samples/AndroidBeam/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..8074c4c
--- /dev/null
+++ b/samples/AndroidBeam/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/icon.png b/samples/AndroidBeam/res/drawable-ldpi/icon.png
similarity index 100%
rename from samples/WeatherListWidget/res/drawable-ldpi/icon.png
rename to samples/AndroidBeam/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/samples/AndroidBeam/res/drawable-mdpi/icon.png b/samples/AndroidBeam/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/samples/AndroidBeam/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/samples/AndroidBeam/res/layout/main.xml b/samples/AndroidBeam/res/layout/main.xml
new file mode 100644
index 0000000..dce6169
--- /dev/null
+++ b/samples/AndroidBeam/res/layout/main.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+**     http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/textView"
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    />
diff --git a/samples/AndroidBeam/res/values/strings.xml b/samples/AndroidBeam/res/values/strings.xml
new file mode 100644
index 0000000..ff4492f
--- /dev/null
+++ b/samples/AndroidBeam/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">Beam</string>
+</resources>
diff --git a/samples/AndroidBeam/src/com/example/android/beam/Beam.java b/samples/AndroidBeam/src/com/example/android/beam/Beam.java
new file mode 100644
index 0000000..17ec325
--- /dev/null
+++ b/samples/AndroidBeam/src/com/example/android/beam/Beam.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.beam;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.nfc.NdefMessage;
+import android.nfc.NdefRecord;
+import android.nfc.NfcAdapter;
+import android.nfc.NfcAdapter.CreateNdefMessageCallback;
+import android.nfc.NfcEvent;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.widget.TextView;
+import android.widget.Toast;
+import java.nio.charset.Charset;
+
+
+public class Beam extends Activity implements CreateNdefMessageCallback {
+    NfcAdapter mNfcAdapter;
+    TextView textView;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+        TextView textView = (TextView) findViewById(R.id.textView);
+        // Check for available NFC Adapter
+        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
+        if (mNfcAdapter == null) {
+            Toast.makeText(this, "NFC is not available", Toast.LENGTH_LONG).show();
+            finish();
+            return;
+        }
+        // Register callback
+        mNfcAdapter.setNdefPushMessageCallback(this, this);
+    }
+
+    @Override
+    public NdefMessage createNdefMessage(NfcEvent event) {
+        String text = ("Beam me up, Android!\n\n" +
+                "Beam Time: " + System.currentTimeMillis());
+        NdefMessage msg = new NdefMessage(
+                new NdefRecord[] { createMimeRecord(
+                        "application/com.example.android.beam", text.getBytes())
+         /**
+          * The Android Application Record (AAR) is commented out. When a device
+          * receives a push with an AAR in it, the application specified in the AAR
+          * is guaranteed to run. The AAR overrides the tag dispatch system.
+          * You can add it back in to guarantee that this
+          * activity starts when receiving a beamed message. For now, this code
+          * uses the tag dispatch system.
+          */
+          //,NdefRecord.createApplicationRecord("com.example.android.beam")
+        });
+        return msg;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        // Check to see that the Activity started due to an Android Beam
+        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
+            processIntent(getIntent());
+        }
+    }
+
+    @Override
+    public void onNewIntent(Intent intent) {
+        // onResume gets called after this to handle the intent
+        setIntent(intent);
+    }
+
+    /**
+     * Parses the NDEF Message from the intent and prints to the TextView
+     */
+    void processIntent(Intent intent) {
+        textView = (TextView) findViewById(R.id.textView);
+        Parcelable[] rawMsgs = intent.getParcelableArrayExtra(
+                NfcAdapter.EXTRA_NDEF_MESSAGES);
+        // only one message sent during the beam
+        NdefMessage msg = (NdefMessage) rawMsgs[0];
+        // record 0 contains the MIME type, record 1 is the AAR, if present
+        textView.setText(new String(msg.getRecords()[0].getPayload()));
+    }
+
+    /**
+     * Creates a custom MIME type encapsulated in an NDEF record
+     *
+     * @param mimeType
+     */
+    public NdefRecord createMimeRecord(String mimeType, byte[] payload) {
+        byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));
+        NdefRecord mimeRecord = new NdefRecord(
+                NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte[0], payload);
+        return mimeRecord;
+    }
+}
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index 39293e1..4a4a7c3 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -1433,6 +1433,20 @@
             </intent-filter>
         </activity>
 
+        <activity android:name=".view.GridLayout0" android:label="Views/Layouts/GridLayout/0. Simple Form (Java)">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
+        <activity android:name=".view.GridLayout1" android:label="Views/Layouts/GridLayout/1. Simple Form (XML)">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+
         <activity android:name=".view.Baseline1" android:label="Views/Layouts/Baseline/1. Top">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
diff --git a/samples/ApiDemos/res/layout/grid_layout_1.xml b/samples/ApiDemos/res/layout/grid_layout_1.xml
new file mode 100644
index 0000000..0e53613
--- /dev/null
+++ b/samples/ApiDemos/res/layout/grid_layout_1.xml
@@ -0,0 +1,87 @@
+<?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.
+-->
+
+<GridLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+
+        android:useDefaultMargins="true"
+        android:alignmentMode="alignBounds"
+        android:rowOrderPreserved="false"
+
+        android:columnCount="4"
+        >
+
+    <TextView
+            android:text="Email setup"
+            android:textSize="32dip"
+
+            android:layout_columnSpan="4"
+            android:layout_gravity="center_horizontal"
+            />
+
+    <TextView
+            android:text="You can configure email in just a few steps:"
+            android:textSize="16dip"
+
+            android:layout_columnSpan="4"
+            android:layout_gravity="left"
+            />
+
+    <TextView
+            android:text="Email address:"
+
+            android:layout_gravity="right"
+            />
+
+    <EditText
+            android:ems="10"
+            />
+
+    <TextView
+            android:text="Password:"
+
+            android:layout_column="0"
+            android:layout_gravity="right"
+            />
+
+    <EditText
+            android:ems="8"
+            />
+
+    <Space
+            android:layout_row="2"
+            android:layout_rowSpan="3"
+            android:layout_column="2"
+            android:layout_gravity="fill"
+            />
+
+    <Button
+            android:text="Manual setup"
+
+            android:layout_row="5"
+            android:layout_column="3"
+            />
+
+    <Button
+            android:text="Next"
+
+            android:layout_column="3"
+            android:layout_gravity="fill_horizontal"
+            />
+</GridLayout>
diff --git a/samples/ApiDemos/res/layout/layout_animations.xml b/samples/ApiDemos/res/layout/layout_animations.xml
index 68f0e0e..ce179c4 100644
--- a/samples/ApiDemos/res/layout/layout_animations.xml
+++ b/samples/ApiDemos/res/layout/layout_animations.xml
@@ -40,34 +40,40 @@
     <LinearLayout
         android:orientation="horizontal"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
+        android:layout_height="wrap_content"
         >
         <CheckBox
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:checked="true"
-            android:text="Appearing Animation"
+            android:text="In"
             android:id="@+id/appearingCB"
             />
         <CheckBox
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:checked="true"
-            android:text="Disappearing Animation"
+            android:text="Out"
             android:id="@+id/disappearingCB"
             />
+    </LinearLayout>
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        >
         <CheckBox
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:checked="true"
-            android:text="Changing/Appearing Animation"
+            android:text="Changing-In"
             android:id="@+id/changingAppearingCB"
             />
         <CheckBox
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:checked="true"
-            android:text="Changing/Disappearing Animation"
+            android:text="Changing-Out"
             android:id="@+id/changingDisappearingCB"
             />
     </LinearLayout>
diff --git a/samples/ApiDemos/res/layout/layout_animations_by_default.xml b/samples/ApiDemos/res/layout/layout_animations_by_default.xml
index a5062bb..6236088 100644
--- a/samples/ApiDemos/res/layout/layout_animations_by_default.xml
+++ b/samples/ApiDemos/res/layout/layout_animations_by_default.xml
@@ -24,18 +24,11 @@
         android:text="Add Button"
         android:id="@+id/addNewButton"
         />
-    <LinearLayout
-        android:orientation="horizontal"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:id="@+id/horizontalContainer"
-        android:animateLayoutChanges="true"
-        />
-    <LinearLayout
-        android:orientation="vertical"
+    <GridLayout
+        android:columnCount="4"
         android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:id="@+id/verticalContainer"
+        android:layout_height="wrap_content"
+        android:id="@+id/gridContainer"
         android:animateLayoutChanges="true"
         />
 </LinearLayout>
diff --git a/samples/ApiDemos/res/layout/layout_animations_hideshow.xml b/samples/ApiDemos/res/layout/layout_animations_hideshow.xml
index 4215ac1..49c2047 100644
--- a/samples/ApiDemos/res/layout/layout_animations_hideshow.xml
+++ b/samples/ApiDemos/res/layout/layout_animations_hideshow.xml
@@ -30,6 +30,12 @@
             android:text="Show Buttons"
             android:id="@+id/addNewButton"
             />
+    </LinearLayout>
+    <LinearLayout
+        android:orientation="horizontal"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        >
         <CheckBox
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.java b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.java
index 65ad782..a2ff23c 100644
--- a/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.java
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimations.java
@@ -20,7 +20,6 @@
 // class is in a sub-package.
 import android.animation.Animator;
 import android.animation.ObjectAnimator;
-import android.widget.LinearLayout;
 import com.example.android.apis.R;
 
 import android.animation.AnimatorListenerAdapter;
@@ -59,8 +58,8 @@
 
         container = new FixedGridLayout(this);
         container.setClipChildren(false);
-        ((FixedGridLayout)container).setCellHeight(50);
-        ((FixedGridLayout)container).setCellWidth(200);
+        ((FixedGridLayout)container).setCellHeight(90);
+        ((FixedGridLayout)container).setCellWidth(100);
         final LayoutTransition transitioner = new LayoutTransition();
         container.setLayoutTransition(transitioner);
         defaultAppearingAnim = transitioner.getAnimator(LayoutTransition.APPEARING);
@@ -83,7 +82,7 @@
         addButton.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
                 Button newButton = new Button(LayoutAnimations.this);
-                newButton.setText("Click to Delete " + (numButtons++));
+                newButton.setText(String.valueOf(numButtons++));
                 newButton.setOnClickListener(new View.OnClickListener() {
                     public void onClick(View v) {
                         container.removeView(v);
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsByDefault.java b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsByDefault.java
index 67b9b51..8898b55 100644
--- a/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsByDefault.java
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsByDefault.java
@@ -21,11 +21,11 @@
 import com.example.android.apis.R;
 
 import android.view.View;
-import android.view.ViewGroup;
 
 import android.app.Activity;
 import android.os.Bundle;
 import android.widget.Button;
+import android.widget.GridLayout;
 
 /**
  * This application demonstrates how to use the animateLayoutChanges tag in XML to automate
@@ -35,36 +35,25 @@
 
     private int numButtons = 1;
 
-    /** Called when the activity is first created. */
     @Override
     public void onCreate(Bundle savedInstanceState) {
 
         super.onCreate(savedInstanceState);
         setContentView(R.layout.layout_animations_by_default);
 
-        final ViewGroup horizontalContainer = (ViewGroup) findViewById(R.id.horizontalContainer);
-        final ViewGroup verticalContainer = (ViewGroup) findViewById(R.id.verticalContainer);
+        final GridLayout gridContainer = (GridLayout) findViewById(R.id.gridContainer);
 
         Button addButton = (Button) findViewById(R.id.addNewButton);
         addButton.setOnClickListener(new View.OnClickListener() {
             public void onClick(View v) {
                 Button newButton = new Button(LayoutAnimationsByDefault.this);
-                newButton.setText("Click To Remove " + (numButtons++));
+                newButton.setText(String.valueOf(numButtons++));
                 newButton.setOnClickListener(new View.OnClickListener() {
                     public void onClick(View v) {
-                        horizontalContainer.removeView(v);
+                        gridContainer.removeView(v);
                     }
                 });
-                horizontalContainer.addView(newButton, Math.min(1, horizontalContainer.getChildCount()));
-
-                newButton = new Button(LayoutAnimationsByDefault.this);
-                newButton.setText("Click To Remove " + (numButtons++));
-                newButton.setOnClickListener(new View.OnClickListener() {
-                    public void onClick(View v) {
-                        verticalContainer.removeView(v);
-                    }
-                });
-                verticalContainer.addView(newButton, Math.min(1, verticalContainer.getChildCount()));
+                gridContainer.addView(newButton, Math.min(1, gridContainer.getChildCount()));
             }
         });
     }
diff --git a/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsHideShow.java b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsHideShow.java
index 1a5d9c0..ac0609e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsHideShow.java
+++ b/samples/ApiDemos/src/com/example/android/apis/animation/LayoutAnimationsHideShow.java
@@ -60,9 +60,9 @@
 
         // Add a slew of buttons to the container. We won't add any more buttons at runtime, but
         // will just show/hide the buttons we've already created
-        for (int i = 0; i < 6; ++i) {
+        for (int i = 0; i < 4; ++i) {
             Button newButton = new Button(this);
-            newButton.setText("Click to Hide " + i);
+            newButton.setText(String.valueOf(i));
             container.addView(newButton);
             newButton.setOnClickListener(new View.OnClickListener() {
                 public void onClick(View v) {
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/GridLayout0.java b/samples/ApiDemos/src/com/example/android/apis/view/GridLayout0.java
new file mode 100644
index 0000000..70de1ac
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/GridLayout0.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Bundle;
+import android.view.View;
+
+import android.widget.*;
+
+import static android.text.InputType.*;
+import static android.widget.GridLayout.*;
+
+/**
+ * A simple form, showing use of the GridLayout API.
+ */
+public class GridLayout0 extends Activity {
+
+    public static View create(Context context) {
+        GridLayout p = new GridLayout(context);
+        p.setUseDefaultMargins(true);
+        p.setAlignmentMode(ALIGN_BOUNDS);
+        p.setRowOrderPreserved(false);
+
+        Spec row1 = spec(0);
+        Spec row2 = spec(1);
+        Spec row3 = spec(2, BASELINE);
+        Spec row4 = spec(3, BASELINE);
+        Spec row5 = spec(2, 3, FILL); // allow the last two rows to overlap the middle two
+        Spec row6 = spec(5);
+        Spec row7 = spec(6);
+
+        Spec col1a = spec(0, 4, CENTER);
+        Spec col1b = spec(0, 4, LEFT);
+        Spec col1c = spec(0, RIGHT);
+        Spec col2 = spec(1, LEFT);
+        Spec col3 = spec(2, FILL);
+        Spec col4a = spec(3);
+        Spec col4b = spec(3, FILL);
+
+        {
+            TextView c = new TextView(context);
+            c.setTextSize(32);
+            c.setText("Email setup");
+            p.addView(c, new LayoutParams(row1, col1a));
+        }
+        {
+            TextView c = new TextView(context);
+            c.setTextSize(16);
+            c.setText("You can configure email in just a few steps:");
+            p.addView(c, new LayoutParams(row2, col1b));
+        }
+        {
+            TextView c = new TextView(context);
+            c.setText("Email address:");
+            p.addView(c, new LayoutParams(row3, col1c));
+        }
+        {
+            EditText c = new EditText(context);
+            c.setEms(10);
+            c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
+            p.addView(c, new LayoutParams(row3, col2));
+        }
+        {
+            TextView c = new TextView(context);
+            c.setText("Password:");
+            p.addView(c, new LayoutParams(row4, col1c));
+        }
+        {
+            TextView c = new EditText(context);
+            c.setEms(8);
+            c.setInputType(TYPE_CLASS_TEXT | TYPE_TEXT_VARIATION_PASSWORD);
+            p.addView(c, new LayoutParams(row4, col2));
+        }
+        {
+            Space c = new Space(context);
+            p.addView(c, new LayoutParams(row5, col3));
+        }
+        {
+            Button c = new Button(context);
+            c.setText("Manual setup");
+            p.addView(c, new LayoutParams(row6, col4a));
+        }
+        {
+            Button c = new Button(context);
+            c.setText("Next");
+            p.addView(c, new LayoutParams(row7, col4b));
+        }
+
+        return p;
+    }
+
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(create(this));
+    }
+
+}
\ No newline at end of file
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/GridLayout1.java b/samples/ApiDemos/src/com/example/android/apis/view/GridLayout1.java
new file mode 100644
index 0000000..f4318e4
--- /dev/null
+++ b/samples/ApiDemos/src/com/example/android/apis/view/GridLayout1.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.apis.view;
+
+import com.example.android.apis.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * A simple form, showing use of the GridLayout API from XML.
+ */
+public class GridLayout1 extends Activity {
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.grid_layout_1);
+    }
+}
diff --git a/samples/ApiDemos/src/com/example/android/apis/view/OverscanActivity.java b/samples/ApiDemos/src/com/example/android/apis/view/OverscanActivity.java
index 3ee63e5..464b601 100644
--- a/samples/ApiDemos/src/com/example/android/apis/view/OverscanActivity.java
+++ b/samples/ApiDemos/src/com/example/android/apis/view/OverscanActivity.java
@@ -99,9 +99,8 @@
     }
     private class OverscanState implements State {
         public void apply() {
-            display("FULLSCREEN + LOW_PROFILE + HIDE_NAVIGATION");
-            mImage.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
-                                       | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
+            display("FULLSCREEN + HIDE_NAVIGATION");
+            mImage.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
         }
         public State next() {
             return new NormalState();
diff --git a/samples/BrowserPlugin/jni/RenderingThread.cpp b/samples/BrowserPlugin/jni/RenderingThread.cpp
index 91ffb4a..1307e90 100644
--- a/samples/BrowserPlugin/jni/RenderingThread.cpp
+++ b/samples/BrowserPlugin/jni/RenderingThread.cpp
@@ -43,9 +43,14 @@
 }
 
 android::status_t RenderingThread::readyToRun() {
+    gLogI.log(kError_ANPLogType, "thread %p acquiring native window...", this);
     while (m_ANW == NULL) {
         m_ANW = gNativeWindowI.acquireNativeWindow(m_npp);
+        if (!m_ANW)
+            gLogI.log(kError_ANPLogType, "thread %p acquire native window FAILED!", this);
+
     }
+    gLogI.log(kError_ANPLogType, "thread %p acquired native window successfully!", this);
 
 #if (!USE_SOFTWARE_RENDERING)
     m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
@@ -165,6 +170,8 @@
                                          const SkBitmap& bitmap)
 {
 #if USE_SOFTWARE_RENDERING
+    if (bitmap.height() == 0 || bitmap.width() == 0)
+        return;
 
     //STEP 1: lock the ANW, getting a buffer
     ANativeWindow_Buffer buffer;
diff --git a/samples/BrowserPlugin/jni/animation/AnimationThread.cpp b/samples/BrowserPlugin/jni/animation/AnimationThread.cpp
index 1388fe3..2729a53 100644
--- a/samples/BrowserPlugin/jni/animation/AnimationThread.cpp
+++ b/samples/BrowserPlugin/jni/animation/AnimationThread.cpp
@@ -45,7 +45,7 @@
     m_paint = new SkPaint;
     m_paint->setAntiAlias(true);
 
-    m_bitmap = constructBitmap(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+    m_bitmap = constructBitmap(0, 0);
     m_canvas = new SkCanvas(*m_bitmap);
 
     m_startExecutionTime = 0;
@@ -95,11 +95,6 @@
     int width, height;
     getDimensions(width, height);
 
-    if (width <= 0)
-        width = DEFAULT_WIDTH;
-    if (height <= 0)
-        height = DEFAULT_HEIGHT;
-
     if (m_bitmap->width() != width || m_bitmap->height() != height) {
         delete m_canvas;
         delete m_bitmap;
diff --git a/samples/BrowserPlugin/jni/animation/AnimationThread.h b/samples/BrowserPlugin/jni/animation/AnimationThread.h
index e95ecce..8222a7e 100644
--- a/samples/BrowserPlugin/jni/animation/AnimationThread.h
+++ b/samples/BrowserPlugin/jni/animation/AnimationThread.h
@@ -59,9 +59,6 @@
     SkPaint* m_paint;
     SkBitmap* m_bitmap;
     SkCanvas* m_canvas;
-
-    static const unsigned int DEFAULT_WIDTH = 400;
-    static const unsigned int DEFAULT_HEIGHT = 400;
 };
 
 
diff --git a/samples/RandomMusicPlayer/Android.mk b/samples/RandomMusicPlayer/Android.mk
new file mode 100644
index 0000000..91637b1
--- /dev/null
+++ b/samples/RandomMusicPlayer/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := RandomMusicPlayer
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/RandomMusicPlayer/AndroidManifest.xml b/samples/RandomMusicPlayer/AndroidManifest.xml
index 5a0fc28..6e52b61 100644
--- a/samples/RandomMusicPlayer/AndroidManifest.xml
+++ b/samples/RandomMusicPlayer/AndroidManifest.xml
@@ -1,30 +1,34 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!--
+  Copyright (C) 2011 The Android Open Source Project
 
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
+  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
+       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. -->
+  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.example.android.musicplayer"
-      android:versionCode="1"
-      android:versionName="1.0">
+    package="com.example.android.musicplayer"
+    android:versionCode="1"
+    android:versionName="1.0">
 
-    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="8" />
-    <uses-permission android:name="android.permission.WAKE_LOCK"/>
+    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="14" />
 
-    <application android:icon="@drawable/ic_launcher" android:label="Random Music Player">
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.WAKE_LOCK" />
+
+    <application android:icon="@drawable/ic_launcher" android:label="@string/app_title">
+
         <activity android:name=".MainActivity"
-                  android:label="Random Music Player"
-                  android:theme="@android:style/Theme.Black.NoTitleBar">
+            android:label="@string/app_title"
+            android:theme="@android:style/Theme.Black.NoTitleBar">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
@@ -33,6 +37,7 @@
 
         <service android:exported="false" android:name=".MusicService">
             <intent-filter>
+                <action android:name="com.example.android.musicplayer.action.TOGGLE_PLAYBACK" />
                 <action android:name="com.example.android.musicplayer.action.PLAY" />
                 <action android:name="com.example.android.musicplayer.action.PAUSE" />
                 <action android:name="com.example.android.musicplayer.action.SKIP" />
@@ -49,6 +54,10 @@
             <intent-filter>
                 <action android:name="android.media.AUDIO_BECOMING_NOISY" />
             </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.MEDIA_BUTTON" />
+            </intent-filter>
         </receiver>
+
     </application>
 </manifest>
diff --git a/samples/RandomMusicPlayer/_index.html b/samples/RandomMusicPlayer/_index.html
index 657e6c4..f719fad 100644
--- a/samples/RandomMusicPlayer/_index.html
+++ b/samples/RandomMusicPlayer/_index.html
@@ -4,5 +4,10 @@
 streamed.  It also illustrates how to use the notification system to indicate
 an ongoing task and how to deal with audio focus changes.</p>
 
+<p><strong>Update:</strong> This sample also illustrates how to use the
+<code><a href="../../../reference/android/media/RemoteControlClient.html">RemoteControlClient</a></code>
+class added in API level 14 to integrate with music playback remote controls
+such as those found on the lockscreen.</p>
+
 <img alt="" src="../images/randommusicplayer.png" />
 
diff --git a/samples/RandomMusicPlayer/default.properties b/samples/RandomMusicPlayer/default.properties
deleted file mode 100644
index e2e8061..0000000
--- a/samples/RandomMusicPlayer/default.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-#
-# This file must be checked in Version Control Systems.
-#
-# To customize properties used by the Ant build system use,
-# "build.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-8
diff --git a/samples/RandomMusicPlayer/res/drawable-hdpi-v11/ic_stat_playing.png b/samples/RandomMusicPlayer/res/drawable-hdpi-v11/ic_stat_playing.png
new file mode 100755
index 0000000..cc62c29
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable-hdpi-v11/ic_stat_playing.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-hdpi-v9/ic_stat_playing.png b/samples/RandomMusicPlayer/res/drawable-hdpi-v9/ic_stat_playing.png
old mode 100644
new mode 100755
index d111aab..9351f4b
--- a/samples/RandomMusicPlayer/res/drawable-hdpi-v9/ic_stat_playing.png
+++ b/samples/RandomMusicPlayer/res/drawable-hdpi-v9/ic_stat_playing.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-hdpi/ic_launcher.png b/samples/RandomMusicPlayer/res/drawable-hdpi/ic_launcher.png
old mode 100644
new mode 100755
index abd9055..972c791
--- a/samples/RandomMusicPlayer/res/drawable-hdpi/ic_launcher.png
+++ b/samples/RandomMusicPlayer/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-hdpi/ic_stat_playing.png b/samples/RandomMusicPlayer/res/drawable-hdpi/ic_stat_playing.png
old mode 100644
new mode 100755
index c1dd9da..099c44e
--- a/samples/RandomMusicPlayer/res/drawable-hdpi/ic_stat_playing.png
+++ b/samples/RandomMusicPlayer/res/drawable-hdpi/ic_stat_playing.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_eject.xml b/samples/RandomMusicPlayer/res/drawable-hdpi/selector_eject.xml
deleted file mode 100644
index 300e75a..0000000
--- a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_eject.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/eject_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/eject_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/eject" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_ff.xml b/samples/RandomMusicPlayer/res/drawable-hdpi/selector_ff.xml
deleted file mode 100644
index 2d399b4..0000000
--- a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_ff.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/ff_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/ff_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/ff" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_pause.xml b/samples/RandomMusicPlayer/res/drawable-hdpi/selector_pause.xml
deleted file mode 100644
index 2d6c4be..0000000
--- a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_pause.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/pause_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/pause_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/pause" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_play.xml b/samples/RandomMusicPlayer/res/drawable-hdpi/selector_play.xml
deleted file mode 100644
index d2eea02..0000000
--- a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_play.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/play_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/play_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/play" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_rew.xml b/samples/RandomMusicPlayer/res/drawable-hdpi/selector_rew.xml
deleted file mode 100644
index 5f5f88a..0000000
--- a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_rew.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/rew_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/rew_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/rew" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_stop.xml b/samples/RandomMusicPlayer/res/drawable-hdpi/selector_stop.xml
deleted file mode 100644
index 5778417..0000000
--- a/samples/RandomMusicPlayer/res/drawable-hdpi/selector_stop.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/stop_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/stop_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/stop" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-ldpi-v9/ic_stat_playing.png b/samples/RandomMusicPlayer/res/drawable-ldpi-v9/ic_stat_playing.png
deleted file mode 100644
index 6a40823..0000000
--- a/samples/RandomMusicPlayer/res/drawable-ldpi-v9/ic_stat_playing.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-ldpi/ic_launcher.png b/samples/RandomMusicPlayer/res/drawable-ldpi/ic_launcher.png
deleted file mode 100644
index 6f1277a..0000000
--- a/samples/RandomMusicPlayer/res/drawable-ldpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-ldpi/ic_stat_playing.png b/samples/RandomMusicPlayer/res/drawable-ldpi/ic_stat_playing.png
deleted file mode 100644
index fb21884..0000000
--- a/samples/RandomMusicPlayer/res/drawable-ldpi/ic_stat_playing.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi-v11/ic_stat_playing.png b/samples/RandomMusicPlayer/res/drawable-mdpi-v11/ic_stat_playing.png
new file mode 100755
index 0000000..049ff3d
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable-mdpi-v11/ic_stat_playing.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi-v9/ic_stat_playing.png b/samples/RandomMusicPlayer/res/drawable-mdpi-v9/ic_stat_playing.png
old mode 100644
new mode 100755
index b5a66df..7970cb9
--- a/samples/RandomMusicPlayer/res/drawable-mdpi-v9/ic_stat_playing.png
+++ b/samples/RandomMusicPlayer/res/drawable-mdpi-v9/ic_stat_playing.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/eject.png b/samples/RandomMusicPlayer/res/drawable-mdpi/eject.png
deleted file mode 100644
index 650b38a..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/eject.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/eject_pressed.png b/samples/RandomMusicPlayer/res/drawable-mdpi/eject_pressed.png
deleted file mode 100644
index 065b30d..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/eject_pressed.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/ff.png b/samples/RandomMusicPlayer/res/drawable-mdpi/ff.png
deleted file mode 100644
index 508f741..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/ff.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/ff_pressed.png b/samples/RandomMusicPlayer/res/drawable-mdpi/ff_pressed.png
deleted file mode 100644
index 468ae8e..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/ff_pressed.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/ic_launcher.png b/samples/RandomMusicPlayer/res/drawable-mdpi/ic_launcher.png
old mode 100644
new mode 100755
index abd9055..01b53fd
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/ic_launcher.png
+++ b/samples/RandomMusicPlayer/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/ic_stat_playing.png b/samples/RandomMusicPlayer/res/drawable-mdpi/ic_stat_playing.png
old mode 100644
new mode 100755
index c1dd9da..5ffc8cc
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/ic_stat_playing.png
+++ b/samples/RandomMusicPlayer/res/drawable-mdpi/ic_stat_playing.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/pause.png b/samples/RandomMusicPlayer/res/drawable-mdpi/pause.png
deleted file mode 100644
index 13581de..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/pause.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/pause_pressed.png b/samples/RandomMusicPlayer/res/drawable-mdpi/pause_pressed.png
deleted file mode 100644
index 9ddd07d..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/pause_pressed.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/play.png b/samples/RandomMusicPlayer/res/drawable-mdpi/play.png
deleted file mode 100644
index e34b48e..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/play.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/play_pressed.png b/samples/RandomMusicPlayer/res/drawable-mdpi/play_pressed.png
deleted file mode 100644
index 790cd29..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/play_pressed.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/rew.png b/samples/RandomMusicPlayer/res/drawable-mdpi/rew.png
deleted file mode 100644
index 26864b7..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/rew.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/rew_pressed.png b/samples/RandomMusicPlayer/res/drawable-mdpi/rew_pressed.png
deleted file mode 100644
index 54c38a7..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/rew_pressed.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_eject.xml b/samples/RandomMusicPlayer/res/drawable-mdpi/selector_eject.xml
deleted file mode 100644
index 300e75a..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_eject.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/eject_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/eject_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/eject" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_ff.xml b/samples/RandomMusicPlayer/res/drawable-mdpi/selector_ff.xml
deleted file mode 100644
index 2d399b4..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_ff.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/ff_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/ff_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/ff" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_pause.xml b/samples/RandomMusicPlayer/res/drawable-mdpi/selector_pause.xml
deleted file mode 100644
index 2d6c4be..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_pause.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/pause_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/pause_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/pause" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_play.xml b/samples/RandomMusicPlayer/res/drawable-mdpi/selector_play.xml
deleted file mode 100644
index d2eea02..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_play.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/play_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/play_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/play" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_rew.xml b/samples/RandomMusicPlayer/res/drawable-mdpi/selector_rew.xml
deleted file mode 100644
index 5f5f88a..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_rew.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/rew_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/rew_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/rew" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_stop.xml b/samples/RandomMusicPlayer/res/drawable-mdpi/selector_stop.xml
deleted file mode 100644
index 5778417..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/selector_stop.xml
+++ /dev/null
@@ -1,22 +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. -->
-
- <selector xmlns:android="http://schemas.android.com/apk/res/android">
-     <item android:state_pressed="true"
-           android:drawable="@drawable/stop_pressed" /> <!-- pressed -->
-     <item android:state_focused="true"
-           android:drawable="@drawable/stop_pressed" /> <!-- focused -->
-     <item android:drawable="@drawable/stop" /> <!-- default -->
- </selector>
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/stop.png b/samples/RandomMusicPlayer/res/drawable-mdpi/stop.png
deleted file mode 100644
index 45eff23..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/stop.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-mdpi/stop_pressed.png b/samples/RandomMusicPlayer/res/drawable-mdpi/stop_pressed.png
deleted file mode 100644
index c7bda81..0000000
--- a/samples/RandomMusicPlayer/res/drawable-mdpi/stop_pressed.png
+++ /dev/null
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-nodpi/dummy_album_art.png b/samples/RandomMusicPlayer/res/drawable-nodpi/dummy_album_art.png
new file mode 100644
index 0000000..e50b97e
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable-nodpi/dummy_album_art.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-xhdpi-v11/ic_stat_playing.png b/samples/RandomMusicPlayer/res/drawable-xhdpi-v11/ic_stat_playing.png
new file mode 100755
index 0000000..f940498
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable-xhdpi-v11/ic_stat_playing.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-xhdpi-v9/ic_stat_playing.png b/samples/RandomMusicPlayer/res/drawable-xhdpi-v9/ic_stat_playing.png
new file mode 100755
index 0000000..d0f2a2b
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable-xhdpi-v9/ic_stat_playing.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-xhdpi/ic_launcher.png b/samples/RandomMusicPlayer/res/drawable-xhdpi/ic_launcher.png
new file mode 100755
index 0000000..af762f2
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable-xhdpi/ic_stat_playing.png b/samples/RandomMusicPlayer/res/drawable-xhdpi/ic_stat_playing.png
new file mode 100755
index 0000000..aa46a0c
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable-xhdpi/ic_stat_playing.png
Binary files differ
diff --git a/samples/RandomMusicPlayer/res/drawable/btn_eject.xml b/samples/RandomMusicPlayer/res/drawable/btn_eject.xml
new file mode 100644
index 0000000..e3e40ae
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable/btn_eject.xml
@@ -0,0 +1,21 @@
+<!--
+  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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/eject_pressed" />
+    <item android:state_focused="true" android:drawable="@drawable/eject_pressed" />
+    <item android:drawable="@drawable/eject" />
+</selector>
diff --git a/samples/RandomMusicPlayer/res/drawable/btn_ff.xml b/samples/RandomMusicPlayer/res/drawable/btn_ff.xml
new file mode 100644
index 0000000..c87fa06
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable/btn_ff.xml
@@ -0,0 +1,21 @@
+<!--
+  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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/ff_pressed" />
+    <item android:state_focused="true" android:drawable="@drawable/ff_pressed" />
+    <item android:drawable="@drawable/ff" />
+</selector>
diff --git a/samples/RandomMusicPlayer/res/drawable/btn_pause.xml b/samples/RandomMusicPlayer/res/drawable/btn_pause.xml
new file mode 100644
index 0000000..7aadd2f
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable/btn_pause.xml
@@ -0,0 +1,21 @@
+<!--
+  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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/pause_pressed" />
+    <item android:state_focused="true" android:drawable="@drawable/pause_pressed" />
+    <item android:drawable="@drawable/pause" />
+</selector>
diff --git a/samples/RandomMusicPlayer/res/drawable/btn_play.xml b/samples/RandomMusicPlayer/res/drawable/btn_play.xml
new file mode 100644
index 0000000..dc319c5
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable/btn_play.xml
@@ -0,0 +1,21 @@
+<!--
+  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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/play_pressed" />
+    <item android:state_focused="true" android:drawable="@drawable/play_pressed" />
+    <item android:drawable="@drawable/play" />
+</selector>
diff --git a/samples/RandomMusicPlayer/res/drawable/btn_rew.xml b/samples/RandomMusicPlayer/res/drawable/btn_rew.xml
new file mode 100644
index 0000000..cc4dad8
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable/btn_rew.xml
@@ -0,0 +1,21 @@
+<!--
+  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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/rew_pressed" />
+    <item android:state_focused="true" android:drawable="@drawable/rew_pressed" />
+    <item android:drawable="@drawable/rew" />
+</selector>
diff --git a/samples/RandomMusicPlayer/res/drawable/btn_stop.xml b/samples/RandomMusicPlayer/res/drawable/btn_stop.xml
new file mode 100644
index 0000000..5ce2d17
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/drawable/btn_stop.xml
@@ -0,0 +1,21 @@
+<!--
+  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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_pressed="true" android:drawable="@drawable/stop_pressed" />
+    <item android:state_focused="true" android:drawable="@drawable/stop_pressed" />
+    <item android:drawable="@drawable/stop" />
+</selector>
diff --git a/samples/RandomMusicPlayer/res/layout-land/main.xml b/samples/RandomMusicPlayer/res/layout-land/main.xml
index c9072bf..b8070bb 100644
--- a/samples/RandomMusicPlayer/res/layout-land/main.xml
+++ b/samples/RandomMusicPlayer/res/layout-land/main.xml
@@ -1,83 +1,68 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!--
+  Copyright (C) 2011 The Android Open Source Project
 
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
+  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
+       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. -->
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:orientation="vertical"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:gravity="center"
-    android:background="#000040"
-    >
+    android:background="#000040">
 
-<TextView android:text="Random Music Player"
-          android:layout_width="wrap_content"
-          android:layout_height="wrap_content"
-          android:padding="20dp"
-          android:textColor="#ffffff"
-          android:textSize="20sp"
-          android:textStyle="bold"
-          />
+    <TextView android:text="@string/app_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="20dp"
+        android:textColor="#ffffff"
+        android:textSize="20sp"
+        android:textStyle="bold" />
 
-<LinearLayout
-    android:orientation="horizontal"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:gravity="center"
-    >
-<Button
-    android:id="@+id/rewindbutton"
-    android:background="@drawable/selector_rew"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
-<Button
-    android:id="@+id/playbutton"
-    android:background="@drawable/selector_play"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
-<Button
-    android:id="@+id/pausebutton"
-    android:background="@drawable/selector_pause"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
-<Button
-    android:id="@+id/skipbutton"
-    android:background="@drawable/selector_ff"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
-<Button
-    android:id="@+id/stopbutton"
-    android:background="@drawable/selector_stop"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
-<Button
-    android:id="@+id/ejectbutton"
-    android:background="@drawable/selector_eject"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
+    <LinearLayout android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center">
+        <Button android:id="@+id/rewindbutton"
+            android:background="@drawable/btn_rew"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
+        <Button android:id="@+id/playbutton"
+            android:background="@drawable/btn_play"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
+        <Button android:id="@+id/pausebutton"
+            android:background="@drawable/btn_pause"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
+        <Button android:id="@+id/skipbutton"
+            android:background="@drawable/btn_ff"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
+        <Button android:id="@+id/stopbutton"
+            android:background="@drawable/btn_stop"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
+        <Button android:id="@+id/ejectbutton"
+            android:background="@drawable/btn_eject"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
 
-</LinearLayout>
+    </LinearLayout>
 </LinearLayout>
diff --git a/samples/RandomMusicPlayer/res/layout-port/main.xml b/samples/RandomMusicPlayer/res/layout-port/main.xml
deleted file mode 100644
index ab86ae5..0000000
--- a/samples/RandomMusicPlayer/res/layout-port/main.xml
+++ /dev/null
@@ -1,93 +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. -->
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    android:gravity="center"
-    android:background="#000040"
-    >
-
-<TextView android:text="Random Music Player"
-          android:layout_width="wrap_content"
-          android:layout_height="wrap_content"
-          android:padding="20dp"
-          android:textColor="#ffffff"
-          android:textSize="20sp"
-          android:textStyle="bold"
-          />
-
-<LinearLayout
-    android:orientation="horizontal"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:gravity="center"
-    android:layout_margin="10dp"
-    >
-<Button
-    android:id="@+id/rewindbutton"
-    android:background="@drawable/selector_rew"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
-<Button
-    android:id="@+id/playbutton"
-    android:background="@drawable/selector_play"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
-<Button
-    android:id="@+id/pausebutton"
-    android:background="@drawable/selector_pause"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
-<Button
-    android:id="@+id/skipbutton"
-    android:background="@drawable/selector_ff"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
-</LinearLayout>
-
-<LinearLayout
-    android:orientation="horizontal"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:gravity="center"
-    android:layout_margin="10dp"
-    >
-<Button
-    android:id="@+id/stopbutton"
-    android:background="@drawable/selector_stop"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
-<Button
-    android:id="@+id/ejectbutton"
-    android:background="@drawable/selector_eject"
-    android:layout_width="64dp"
-    android:layout_height="64dp"
-    android:layout_margin="5dp"
-    />
-
-</LinearLayout>
-</LinearLayout>
diff --git a/samples/RandomMusicPlayer/res/layout/main.xml b/samples/RandomMusicPlayer/res/layout/main.xml
new file mode 100644
index 0000000..a41a710
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/layout/main.xml
@@ -0,0 +1,76 @@
+<!--
+  Copyright (C) 2011 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    android:gravity="center"
+    android:background="#000040">
+
+    <TextView android:text="@string/app_title"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:padding="20dp"
+        android:textColor="#ffffff"
+        android:textSize="20sp"
+        android:textStyle="bold" />
+
+    <LinearLayout android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:layout_margin="10dp">
+        <Button android:id="@+id/rewindbutton"
+            android:background="@drawable/btn_rew"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
+        <Button android:id="@+id/playbutton"
+            android:background="@drawable/btn_play"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
+        <Button android:id="@+id/pausebutton"
+            android:background="@drawable/btn_pause"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
+        <Button android:id="@+id/skipbutton"
+            android:background="@drawable/btn_ff"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
+    </LinearLayout>
+
+    <LinearLayout android:orientation="horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:layout_margin="10dp">
+        <Button android:id="@+id/stopbutton"
+            android:background="@drawable/btn_stop"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
+        <Button android:id="@+id/ejectbutton"
+            android:background="@drawable/btn_eject"
+            android:layout_width="64dp"
+            android:layout_height="64dp"
+            android:layout_margin="5dp" />
+
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/RandomMusicPlayer/res/values/strings.xml b/samples/RandomMusicPlayer/res/values/strings.xml
new file mode 100644
index 0000000..39db75e
--- /dev/null
+++ b/samples/RandomMusicPlayer/res/values/strings.xml
@@ -0,0 +1,19 @@
+<!--
+  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>
+    <string name="app_title">Random Music Player</string>
+</resources>
diff --git a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/AudioFocusHelper.java b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/AudioFocusHelper.java
index 4b8b54a..980bac8 100644
--- a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/AudioFocusHelper.java
+++ b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/AudioFocusHelper.java
@@ -51,7 +51,6 @@
      * Called by AudioManager on audio focus changes. We implement this by calling our
      * MusicFocusable appropriately to relay the message.
      */
-    @Override
     public void onAudioFocusChange(int focusChange) {
         if (mFocusable == null) return;
         switch (focusChange) {
diff --git a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MainActivity.java b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MainActivity.java
index 4974a21..4d5224b 100644
--- a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MainActivity.java
+++ b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MainActivity.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Bundle;
+import android.view.KeyEvent;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
@@ -71,7 +72,6 @@
         mEjectButton.setOnClickListener(this);
     }
 
-    @Override
     public void onClick(View target) {
         // Send the correct intent to the MusicService, according to the button that was clicked
         if (target == mPlayButton)
@@ -119,4 +119,15 @@
 
         alertBuilder.show();
     }
+
+    @Override
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+            case KeyEvent.KEYCODE_HEADSETHOOK:
+                startService(new Intent(MusicService.ACTION_TOGGLE_PLAYBACK));
+                return true;
+        }
+        return super.onKeyDown(keyCode, event);
+    }
 }
diff --git a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MediaButtonHelper.java b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MediaButtonHelper.java
new file mode 100644
index 0000000..1bacee5
--- /dev/null
+++ b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MediaButtonHelper.java
@@ -0,0 +1,85 @@
+package com.example.android.musicplayer;
+
+import android.content.ComponentName;
+import android.media.AudioManager;
+import android.util.Log;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+/**
+ * Class that assists with handling new media button APIs available in API level 8.
+ */
+public class MediaButtonHelper {
+    // Backwards compatibility code (methods available as of API Level 8)
+    private static final String TAG = "MediaButtonHelper";
+
+    static {
+        initializeStaticCompatMethods();
+    }
+
+    static Method sMethodRegisterMediaButtonEventReceiver;
+    static Method sMethodUnregisterMediaButtonEventReceiver;
+
+    static void initializeStaticCompatMethods() {
+        try {
+            sMethodRegisterMediaButtonEventReceiver = AudioManager.class.getMethod(
+                    "registerMediaButtonEventReceiver",
+                    new Class[] { ComponentName.class });
+            sMethodUnregisterMediaButtonEventReceiver = AudioManager.class.getMethod(
+                    "unregisterMediaButtonEventReceiver",
+                    new Class[] { ComponentName.class });
+        } catch (NoSuchMethodException e) {
+            // Silently fail when running on an OS before API level 8.
+        }
+    }
+
+    public static void registerMediaButtonEventReceiverCompat(AudioManager audioManager,
+            ComponentName receiver) {
+        if (sMethodRegisterMediaButtonEventReceiver == null)
+            return;
+
+        try {
+            sMethodRegisterMediaButtonEventReceiver.invoke(audioManager, receiver);
+        } catch (InvocationTargetException e) {
+            // Unpack original exception when possible
+            Throwable cause = e.getCause();
+            if (cause instanceof RuntimeException) {
+                throw (RuntimeException) cause;
+            } else if (cause instanceof Error) {
+                throw (Error) cause;
+            } else {
+                // Unexpected checked exception; wrap and re-throw
+                throw new RuntimeException(e);
+            }
+        } catch (IllegalAccessException e) {
+            Log.e(TAG, "IllegalAccessException invoking registerMediaButtonEventReceiver.");
+            e.printStackTrace();
+        }
+    }
+
+    @SuppressWarnings("unused")
+    public static void unregisterMediaButtonEventReceiverCompat(AudioManager audioManager,
+            ComponentName receiver) {
+        if (sMethodUnregisterMediaButtonEventReceiver == null)
+            return;
+
+        try {
+            sMethodUnregisterMediaButtonEventReceiver.invoke(audioManager, receiver);
+        } catch (InvocationTargetException e) {
+            // Unpack original exception when possible
+            Throwable cause = e.getCause();
+            if (cause instanceof RuntimeException) {
+                throw (RuntimeException) cause;
+            } else if (cause instanceof Error) {
+                throw (Error) cause;
+            } else {
+                // Unexpected checked exception; wrap and re-throw
+                throw new RuntimeException(e);
+            }
+        } catch (IllegalAccessException e) {
+            Log.e(TAG, "IllegalAccessException invoking unregisterMediaButtonEventReceiver.");
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicIntentReceiver.java b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicIntentReceiver.java
index cc03d5e..28f19d4 100644
--- a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicIntentReceiver.java
+++ b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicIntentReceiver.java
@@ -19,22 +19,53 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
+import android.util.Log;
+import android.view.KeyEvent;
 import android.widget.Toast;
 
 /**
  * Receives broadcasted intents. In particular, we are interested in the
- * android.media.AUDIO_BECOMING_NOISY intent, which is broadcast, for example, when the user
- * disconnects the headphones. This class works because we are declaring it in a &lt;receiver&gt;
- * tag in AndroidManifest.xml.
+ * android.media.AUDIO_BECOMING_NOISY and android.intent.action.MEDIA_BUTTON intents, which is
+ * broadcast, for example, when the user disconnects the headphones. This class works because we are
+ * declaring it in a &lt;receiver&gt; tag in AndroidManifest.xml.
  */
 public class MusicIntentReceiver extends BroadcastReceiver {
     @Override
-    public void onReceive(Context ctx, Intent intent) {
+    public void onReceive(Context context, Intent intent) {
         if (intent.getAction().equals(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
-            Toast.makeText(ctx, "Headphones disconnected.", Toast.LENGTH_SHORT).show();
+            Toast.makeText(context, "Headphones disconnected.", Toast.LENGTH_SHORT).show();
 
             // send an intent to our MusicService to telling it to pause the audio
-            ctx.startService(new Intent(MusicService.ACTION_PAUSE));
+            context.startService(new Intent(MusicService.ACTION_PAUSE));
+
+        } else if (intent.getAction().equals(Intent.ACTION_MEDIA_BUTTON)) {
+            KeyEvent keyEvent = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT);
+            if (keyEvent.getAction() != KeyEvent.ACTION_DOWN)
+                return;
+
+            switch (keyEvent.getKeyCode()) {
+                case KeyEvent.KEYCODE_HEADSETHOOK:
+                case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                    context.startService(new Intent(MusicService.ACTION_TOGGLE_PLAYBACK));
+                    break;
+                case KeyEvent.KEYCODE_MEDIA_PLAY:
+                    context.startService(new Intent(MusicService.ACTION_PLAY));
+                    break;
+                case KeyEvent.KEYCODE_MEDIA_PAUSE:
+                    context.startService(new Intent(MusicService.ACTION_PAUSE));
+                    break;
+                case KeyEvent.KEYCODE_MEDIA_STOP:
+                    context.startService(new Intent(MusicService.ACTION_STOP));
+                    break;
+                case KeyEvent.KEYCODE_MEDIA_NEXT:
+                    context.startService(new Intent(MusicService.ACTION_SKIP));
+                    break;
+                case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+                    // TODO: ensure that doing this in rapid succession actually plays the
+                    // previous song
+                    context.startService(new Intent(MusicService.ACTION_REWIND));
+                    break;
+            }
         }
     }
 }
diff --git a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicRetriever.java b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicRetriever.java
index 44d6447..5e6f2f1 100644
--- a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicRetriever.java
+++ b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicRetriever.java
@@ -16,16 +16,17 @@
 
 package com.example.android.musicplayer;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-
 import android.content.ContentResolver;
 import android.content.ContentUris;
 import android.database.Cursor;
 import android.net.Uri;
+import android.provider.MediaStore;
 import android.util.Log;
 
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
 /**
  * Retrieves and organizes media to play. Before being used, you must call {@link #prepare()},
  * which will retrieve all of the music on the user's device (by performing a query on a content
@@ -57,7 +58,8 @@
 
         // Perform a query on the content resolver. The URI we're passing specifies that we
         // want to query for all audio media on external storage (e.g. SD card)
-        Cursor cur = mContentResolver.query(uri, null, null, null, null);
+        Cursor cur = mContentResolver.query(uri, null,
+                MediaStore.Audio.Media.IS_MUSIC + " = 1", null, null);
         Log.i(TAG, "Query finished. " + (cur == null ? "Returned NULL." : "Returned a cursor."));
 
         if (cur == null) {
@@ -73,9 +75,12 @@
 
         Log.i(TAG, "Listing...");
 
-        // retrieve the indices of the columns where the ID and title of the song are
-        int titleColumn = cur.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
-        int idColumn = cur.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
+        // retrieve the indices of the columns where the ID, title, etc. of the song are
+        int artistColumn = cur.getColumnIndex(MediaStore.Audio.Media.ARTIST);
+        int titleColumn = cur.getColumnIndex(MediaStore.Audio.Media.TITLE);
+        int albumColumn = cur.getColumnIndex(MediaStore.Audio.Media.ALBUM);
+        int durationColumn = cur.getColumnIndex(MediaStore.Audio.Media.DURATION);
+        int idColumn = cur.getColumnIndex(MediaStore.Audio.Media._ID);
 
         Log.i(TAG, "Title column index: " + String.valueOf(titleColumn));
         Log.i(TAG, "ID column index: " + String.valueOf(titleColumn));
@@ -83,7 +88,12 @@
         // add each song to mItems
         do {
             Log.i(TAG, "ID: " + cur.getString(idColumn) + " Title: " + cur.getString(titleColumn));
-            mItems.add(new Item(cur.getLong(idColumn), cur.getString(titleColumn)));
+            mItems.add(new Item(
+                    cur.getLong(idColumn),
+                    cur.getString(artistColumn),
+                    cur.getString(titleColumn),
+                    cur.getString(albumColumn),
+                    cur.getLong(durationColumn)));
         } while (cur.moveToNext());
 
         Log.i(TAG, "Done querying media. MusicRetriever is ready.");
@@ -99,17 +109,41 @@
         return mItems.get(mRandom.nextInt(mItems.size()));
     }
 
-    public class Item {
+    public static class Item {
         long id;
+        String artist;
         String title;
+        String album;
+        long duration;
 
-        public Item(long id, String title) {
+        public Item(long id, String artist, String title, String album, long duration) {
             this.id = id;
+            this.artist = artist;
             this.title = title;
+            this.album = album;
+            this.duration = duration;
         }
 
-        public long getId() { return id; }
-        public String getTitle() { return title; }
+        public long getId() {
+            return id;
+        }
+
+        public String getArtist() {
+            return artist;
+        }
+
+        public String getTitle() {
+            return title;
+        }
+
+        public String getAlbum() {
+            return album;
+        }
+
+        public long getDuration() {
+            return duration;
+        }
+
         public Uri getURI() {
             return ContentUris.withAppendedId(
                     android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
diff --git a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicService.java b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicService.java
index 9bd1251..25f5d81 100644
--- a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicService.java
+++ b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/MusicService.java
@@ -16,19 +16,22 @@
 
 package com.example.android.musicplayer;
 
-import java.io.IOException;
-
 import android.app.Notification;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.media.AudioManager;
+import android.media.MediaMetadataRetriever;
 import android.media.MediaPlayer;
 import android.media.MediaPlayer.OnCompletionListener;
 import android.media.MediaPlayer.OnErrorListener;
 import android.media.MediaPlayer.OnPreparedListener;
+import android.media.RemoteControlClient;
 import android.net.Uri;
 import android.net.wifi.WifiManager;
 import android.net.wifi.WifiManager.WifiLock;
@@ -37,9 +40,11 @@
 import android.util.Log;
 import android.widget.Toast;
 
+import java.io.IOException;
+
 /**
  * Service that handles media playback. This is the Service through which we perform all the media
- * handling in our application. Upon initialization, it starts a {@link MediaRetriever} to scan
+ * handling in our application. Upon initialization, it starts a {@link MusicRetriever} to scan
  * the user's media. Then, it waits for Intents (which come from our main activity,
  * {@link MainActivity}, which signal the service to perform specific operations: Play, Pause,
  * Rewind, Skip, etc.
@@ -48,7 +53,25 @@
                 OnErrorListener, MusicFocusable,
                 PrepareMusicRetrieverTask.MusicRetrieverPreparedListener {
 
-    NotificationManager mNotificationManager;
+    // The tag we put on debug messages
+    final static String TAG = "RandomMusicPlayer";
+
+    // These are the Intent actions that we are prepared to handle. Notice that the fact these
+    // constants exist in our class is a mere convenience: what really defines the actions our
+    // service can handle are the <action> tags in the <intent-filters> tag for our service in
+    // AndroidManifest.xml.
+    public static final String ACTION_TOGGLE_PLAYBACK =
+            "com.example.android.musicplayer.action.TOGGLE_PLAYBACK";
+    public static final String ACTION_PLAY = "com.example.android.musicplayer.action.PLAY";
+    public static final String ACTION_PAUSE = "com.example.android.musicplayer.action.PAUSE";
+    public static final String ACTION_STOP = "com.example.android.musicplayer.action.STOP";
+    public static final String ACTION_SKIP = "com.example.android.musicplayer.action.SKIP";
+    public static final String ACTION_REWIND = "com.example.android.musicplayer.action.REWIND";
+    public static final String ACTION_URL = "com.example.android.musicplayer.action.URL";
+
+    // The volume we set the media player to when we lose audio focus, but are allowed to reduce
+    // the volume instead of stopping playback.
+    public static final float DUCK_VOLUME = 0.1f;
 
     // our media player
     MediaPlayer mPlayer = null;
@@ -104,24 +127,6 @@
     // device from shutting off the Wifi radio
     WifiLock mWifiLock;
 
-    // The tag we put on debug messages
-    final static String TAG = "RandomMusicPlayer";
-
-    // These are the Intent actions that we are prepared to handle. Notice that the fact these
-    // constants exist in our class is a mere convenience: what really defines the actions our
-    // service can handle are the <action> tags in the <intent-filters> tag for our service in
-    // AndroidManifest.xml.
-    public static final String ACTION_PLAY = "com.example.android.musicplayer.action.PLAY";
-    public static final String ACTION_PAUSE = "com.example.android.musicplayer.action.PAUSE";
-    public static final String ACTION_STOP = "com.example.android.musicplayer.action.STOP";
-    public static final String ACTION_SKIP = "com.example.android.musicplayer.action.SKIP";
-    public static final String ACTION_REWIND = "com.example.android.musicplayer.action.REWIND";
-    public static final String ACTION_URL = "com.example.android.musicplayer.action.URL";
-
-    // The volume we set the media player to when we lose audio focus, but are allowed to reduce
-    // the volume instead of stopping playback.
-    public final float DUCK_VOLUME = 0.1f;
-
     // The ID we use for the notification (the onscreen alert that appears at the notification
     // area at the top of the screen as an icon -- and as text as well if the user expands the
     // notification area).
@@ -131,6 +136,20 @@
     // providing titles and URIs as we need.
     MusicRetriever mRetriever;
 
+    // our RemoteControlClient object, which will use remote control APIs available in
+    // SDK level >= 14, if they're available.
+    RemoteControlClientCompat mRemoteControlClientCompat;
+
+    // Dummy album art we will pass to the remote control (if the APIs are available).
+    Bitmap mDummyAlbumArt;
+
+    // The component name of MusicIntentReceiver, for use with media button and remote control
+    // APIs
+    ComponentName mMediaButtonReceiverComponent;
+
+    AudioManager mAudioManager;
+    NotificationManager mNotificationManager;
+
     Notification mNotification = null;
 
     /**
@@ -167,6 +186,7 @@
                         .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
 
         mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+        mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
 
         // Create the retriever and start an asynchronous task that will prepare it.
         mRetriever = new MusicRetriever(getContentResolver());
@@ -177,6 +197,10 @@
             mAudioFocusHelper = new AudioFocusHelper(getApplicationContext(), this);
         else
             mAudioFocus = AudioFocus.Focused; // no focus feature, so we always "have" audio focus
+
+        mDummyAlbumArt = BitmapFactory.decodeResource(getResources(), R.drawable.dummy_album_art);
+
+        mMediaButtonReceiverComponent = new ComponentName(this, MusicIntentReceiver.class);
     }
 
     /**
@@ -187,7 +211,8 @@
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
         String action = intent.getAction();
-        if (action.equals(ACTION_PLAY)) processPlayRequest();
+        if (action.equals(ACTION_TOGGLE_PLAYBACK)) processTogglePlaybackRequest();
+        else if (action.equals(ACTION_PLAY)) processPlayRequest();
         else if (action.equals(ACTION_PAUSE)) processPauseRequest();
         else if (action.equals(ACTION_SKIP)) processSkipRequest();
         else if (action.equals(ACTION_STOP)) processStopRequest();
@@ -198,6 +223,14 @@
                                  // restart in case it's killed.
     }
 
+    void processTogglePlaybackRequest() {
+        if (mState == State.Paused || mState == State.Stopped) {
+            processPlayRequest();
+        } else {
+            processPauseRequest();
+        }
+    }
+
     void processPlayRequest() {
         if (mState == State.Retrieving) {
             // If we are still retrieving media, just set the flag to start playing when we're
@@ -209,6 +242,8 @@
 
         tryToGetAudioFocus();
 
+        // actually play the song
+
         if (mState == State.Stopped) {
             // If we're stopped, just go ahead to the next song and start playing
             playNextSong(null);
@@ -219,6 +254,12 @@
             setUpAsForeground(mSongTitle + " (playing)");
             configAndStartMediaPlayer();
         }
+
+        // Tell any remote controls that our playback state is 'playing'.
+        if (mRemoteControlClientCompat != null) {
+            mRemoteControlClientCompat
+                    .setPlaybackState(RemoteControlClient.PLAYSTATE_PLAYING);
+        }
     }
 
     void processPauseRequest() {
@@ -234,7 +275,13 @@
             mState = State.Paused;
             mPlayer.pause();
             relaxResources(false); // while paused, we always retain the MediaPlayer
-            giveUpAudioFocus();
+            // do not give up audio focus
+        }
+
+        // Tell any remote controls that our playback state is 'paused'.
+        if (mRemoteControlClientCompat != null) {
+            mRemoteControlClientCompat
+                    .setPlaybackState(RemoteControlClient.PLAYSTATE_PAUSED);
         }
     }
 
@@ -251,13 +298,23 @@
     }
 
     void processStopRequest() {
-        if (mState == State.Playing || mState == State.Paused) {
+        processStopRequest(false);
+    }
+
+    void processStopRequest(boolean force) {
+        if (mState == State.Playing || mState == State.Paused || force) {
             mState = State.Stopped;
 
             // let go of all resources...
             relaxResources(true);
             giveUpAudioFocus();
 
+            // Tell any remote controls that our playback state is 'paused'.
+            if (mRemoteControlClientCompat != null) {
+                mRemoteControlClientCompat
+                        .setPlaybackState(RemoteControlClient.PLAYSTATE_STOPPED);
+            }
+
             // service is no longer necessary. Will be started again if needed.
             stopSelf();
         }
@@ -330,14 +387,6 @@
         }
     }
 
-    /**
-     * Shortcut to making and displaying a toast. Seemed cleaner than repeating
-     * this code everywhere, at least for this sample.
-     */
-    void say(String message) {
-        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
-    }
-
     void tryToGetAudioFocus() {
         if (mAudioFocus != AudioFocus.Focused && mAudioFocusHelper != null
                         && mAudioFocusHelper.requestFocus())
@@ -355,34 +404,80 @@
         relaxResources(false); // release everything except MediaPlayer
 
         try {
+            MusicRetriever.Item playingItem = null;
             if (manualUrl != null) {
                 // set the source of the media player to a manual URL or path
                 createMediaPlayerIfNeeded();
                 mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
                 mPlayer.setDataSource(manualUrl);
-                mSongTitle = manualUrl;
                 mIsStreaming = manualUrl.startsWith("http:") || manualUrl.startsWith("https:");
+
+                playingItem = new MusicRetriever.Item(0, null, manualUrl, null, 0);
             }
             else {
                 mIsStreaming = false; // playing a locally available song
 
-                MusicRetriever.Item item = mRetriever.getRandomItem();
-                if (item == null) {
-                    say("No song to play :-(");
+                playingItem = mRetriever.getRandomItem();
+                if (playingItem == null) {
+                    Toast.makeText(this,
+                            "No available music to play. Place some music on your external storage "
+                            + "device (e.g. your SD card) and try again.",
+                            Toast.LENGTH_LONG).show();
+                    processStopRequest(true); // stop everything!
                     return;
                 }
 
                 // set the source of the media player a a content URI
                 createMediaPlayerIfNeeded();
                 mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
-                mPlayer.setDataSource(getApplicationContext(), item.getURI());
-                mSongTitle = item.getTitle();
+                mPlayer.setDataSource(getApplicationContext(), playingItem.getURI());
             }
 
+            mSongTitle = playingItem.getTitle();
 
             mState = State.Preparing;
             setUpAsForeground(mSongTitle + " (loading)");
 
+            // Use the media button APIs (if available) to register ourselves for media button
+            // events
+
+            MediaButtonHelper.registerMediaButtonEventReceiverCompat(
+                    mAudioManager, mMediaButtonReceiverComponent);
+
+            // Use the remote control APIs (if available) to set the playback state
+
+            if (mRemoteControlClientCompat == null) {
+                Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+                intent.setComponent(mMediaButtonReceiverComponent);
+                mRemoteControlClientCompat = new RemoteControlClientCompat(
+                        PendingIntent.getBroadcast(this /*context*/,
+                                0 /*requestCode, ignored*/, intent /*intent*/, 0 /*flags*/));
+                RemoteControlHelper.registerRemoteControlClient(mAudioManager,
+                        mRemoteControlClientCompat);
+            }
+
+            mRemoteControlClientCompat.setPlaybackState(
+                    RemoteControlClient.PLAYSTATE_PLAYING);
+
+            mRemoteControlClientCompat.setTransportControlFlags(
+                    RemoteControlClient.FLAG_KEY_MEDIA_PLAY |
+                    RemoteControlClient.FLAG_KEY_MEDIA_PAUSE |
+                    RemoteControlClient.FLAG_KEY_MEDIA_NEXT |
+                    RemoteControlClient.FLAG_KEY_MEDIA_STOP);
+
+            // Update the remote controls
+            mRemoteControlClientCompat.editMetadata(true)
+                    .putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, playingItem.getArtist())
+                    .putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, playingItem.getAlbum())
+                    .putString(MediaMetadataRetriever.METADATA_KEY_TITLE, playingItem.getTitle())
+                    .putLong(MediaMetadataRetriever.METADATA_KEY_DURATION,
+                            playingItem.getDuration())
+                    // TODO: fetch real item artwork
+                    .putBitmap(
+                            RemoteControlClientCompat.MetadataEditorCompat.METADATA_KEY_ARTWORK,
+                            mDummyAlbumArt)
+                    .apply();
+
             // starts preparing the media player in the background. When it's done, it will call
             // our OnPreparedListener (that is, the onPrepared() method on this class, since we set
             // the listener to 'this').
@@ -403,14 +498,12 @@
     }
 
     /** Called when media player is done playing current song. */
-    @Override
     public void onCompletion(MediaPlayer player) {
         // The media player finished playing the current song, so we go ahead and start the next.
         playNextSong(null);
     }
 
     /** Called when media player is done preparing. */
-    @Override
     public void onPrepared(MediaPlayer player) {
         // The media player is done preparing. That means we can start playing!
         mState = State.Playing;
@@ -449,7 +542,6 @@
      * Called when there's an error playing media. When this happens, the media player goes to
      * the Error state. We warn the user about the error and reset the media player.
      */
-    @Override
     public boolean onError(MediaPlayer mp, int what, int extra) {
         Toast.makeText(getApplicationContext(), "Media player error! Resetting.",
             Toast.LENGTH_SHORT).show();
@@ -461,7 +553,6 @@
         return true; // true indicates we handled the error
     }
 
-    @Override
     public void onGainedAudioFocus() {
         Toast.makeText(getApplicationContext(), "gained audio focus.", Toast.LENGTH_SHORT).show();
         mAudioFocus = AudioFocus.Focused;
@@ -471,7 +562,6 @@
             configAndStartMediaPlayer();
     }
 
-    @Override
     public void onLostAudioFocus(boolean canDuck) {
         Toast.makeText(getApplicationContext(), "lost audio focus." + (canDuck ? "can duck" :
             "no duck"), Toast.LENGTH_SHORT).show();
@@ -482,7 +572,6 @@
             configAndStartMediaPlayer();
     }
 
-    @Override
     public void onMusicRetrieverPrepared() {
         // Done retrieving!
         mState = State.Stopped;
diff --git a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/RemoteControlClientCompat.java b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/RemoteControlClientCompat.java
new file mode 100644
index 0000000..9541a91
--- /dev/null
+++ b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/RemoteControlClientCompat.java
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.musicplayer;
+
+import android.app.PendingIntent;
+import android.graphics.Bitmap;
+import android.os.Looper;
+import android.util.Log;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ * RemoteControlClient enables exposing information meant to be consumed by remote controls capable
+ * of displaying metadata, artwork and media transport control buttons. A remote control client
+ * object is associated with a media button event receiver. This event receiver must have been
+ * previously registered with
+ * {@link android.media.AudioManager#registerMediaButtonEventReceiver(android.content.ComponentName)}
+ * before the RemoteControlClient can be registered through
+ * {@link android.media.AudioManager#registerRemoteControlClient(android.media.RemoteControlClient)}.
+ */
+@SuppressWarnings({"rawtypes", "unchecked"})
+public class RemoteControlClientCompat {
+
+    private static final String TAG = "RemoteControlCompat";
+
+    private static Class sRemoteControlClientClass;
+
+    // RCC short for RemoteControlClient
+    private static Method sRCCEditMetadataMethod;
+    private static Method sRCCSetPlayStateMethod;
+    private static Method sRCCSetTransportControlFlags;
+
+    private static boolean sHasRemoteControlAPIs = false;
+
+    static {
+        try {
+            ClassLoader classLoader = RemoteControlClientCompat.class.getClassLoader();
+            sRemoteControlClientClass = getActualRemoteControlClientClass(classLoader);
+            // dynamically populate the playstate and flag values in case they change
+            // in future versions.
+            for (Field field : RemoteControlClientCompat.class.getFields()) {
+                try {
+                    Field realField = sRemoteControlClientClass.getField(field.getName());
+                    Object realValue = realField.get(null);
+                    field.set(null, realValue);
+                } catch (NoSuchFieldException e) {
+                    Log.w(TAG, "Could not get real field: " + field.getName());
+                } catch (IllegalArgumentException e) {
+                    Log.w(TAG, "Error trying to pull field value for: " + field.getName()
+                            + " " + e.getMessage());
+                } catch (IllegalAccessException e) {
+                    Log.w(TAG, "Error trying to pull field value for: " + field.getName()
+                            + " " + e.getMessage());
+                }
+            }
+
+            // get the required public methods on RemoteControlClient
+            sRCCEditMetadataMethod = sRemoteControlClientClass.getMethod("editMetadata",
+                    boolean.class);
+            sRCCSetPlayStateMethod = sRemoteControlClientClass.getMethod("setPlaybackState",
+                    int.class);
+            sRCCSetTransportControlFlags = sRemoteControlClientClass.getMethod(
+                    "setTransportControlFlags", int.class);
+
+            sHasRemoteControlAPIs = true;
+        } catch (ClassNotFoundException e) {
+            // Silently fail when running on an OS before ICS.
+        } catch (NoSuchMethodException e) {
+            // Silently fail when running on an OS before ICS.
+        } catch (IllegalArgumentException e) {
+            // Silently fail when running on an OS before ICS.
+        } catch (SecurityException e) {
+            // Silently fail when running on an OS before ICS.
+        }
+    }
+
+    public static Class getActualRemoteControlClientClass(ClassLoader classLoader)
+            throws ClassNotFoundException {
+        return classLoader.loadClass("android.media.RemoteControlClient");
+    }
+
+    private Object mActualRemoteControlClient;
+
+    public RemoteControlClientCompat(PendingIntent pendingIntent) {
+        if (!sHasRemoteControlAPIs) {
+            return;
+        }
+        try {
+            mActualRemoteControlClient =
+                    sRemoteControlClientClass.getConstructor(PendingIntent.class)
+                            .newInstance(pendingIntent);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public RemoteControlClientCompat(PendingIntent pendingIntent, Looper looper) {
+        if (!sHasRemoteControlAPIs) {
+            return;
+        }
+
+        try {
+            mActualRemoteControlClient =
+                    sRemoteControlClientClass.getConstructor(PendingIntent.class, Looper.class)
+                            .newInstance(pendingIntent, looper);
+        } catch (Exception e) {
+            Log.e(TAG, "Error creating new instance of " + sRemoteControlClientClass.getName(), e);
+        }
+    }
+
+    /**
+     * Class used to modify metadata in a {@link android.media.RemoteControlClient} object. Use
+     * {@link android.media.RemoteControlClient#editMetadata(boolean)} to create an instance of an
+     * editor, on which you set the metadata for the RemoteControlClient instance. Once all the
+     * information has been set, use {@link #apply()} to make it the new metadata that should be
+     * displayed for the associated client. Once the metadata has been "applied", you cannot reuse
+     * this instance of the MetadataEditor.
+     */
+    public class MetadataEditorCompat {
+
+        private Method mPutStringMethod;
+        private Method mPutBitmapMethod;
+        private Method mPutLongMethod;
+        private Method mClearMethod;
+        private Method mApplyMethod;
+
+        private Object mActualMetadataEditor;
+
+        /**
+         * The metadata key for the content artwork / album art.
+         */
+        public final static int METADATA_KEY_ARTWORK = 100;
+
+        private MetadataEditorCompat(Object actualMetadataEditor) {
+            if (sHasRemoteControlAPIs && actualMetadataEditor == null) {
+                throw new IllegalArgumentException("Remote Control API's exist, " +
+                        "should not be given a null MetadataEditor");
+            }
+            if (sHasRemoteControlAPIs) {
+                Class metadataEditorClass = actualMetadataEditor.getClass();
+
+                try {
+                    mPutStringMethod = metadataEditorClass.getMethod("putString",
+                            int.class, String.class);
+                    mPutBitmapMethod = metadataEditorClass.getMethod("putBitmap",
+                            int.class, Bitmap.class);
+                    mPutLongMethod = metadataEditorClass.getMethod("putLong",
+                            int.class, long.class);
+                    mClearMethod = metadataEditorClass.getMethod("clear", new Class[]{});
+                    mApplyMethod = metadataEditorClass.getMethod("apply", new Class[]{});
+                } catch (Exception e) {
+                    throw new RuntimeException(e.getMessage(), e);
+                }
+            }
+            mActualMetadataEditor = actualMetadataEditor;
+        }
+
+        /**
+         * Adds textual information to be displayed.
+         * Note that none of the information added after {@link #apply()} has been called,
+         * will be displayed.
+         * @param key The identifier of a the metadata field to set. Valid values are
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}.
+         * @param value The text for the given key, or {@code null} to signify there is no valid
+         *      information for the field.
+         * @return Returns a reference to the same MetadataEditor object, so you can chain put
+         *      calls together.
+         */
+        public MetadataEditorCompat putString(int key, String value) {
+            if (sHasRemoteControlAPIs) {
+                try {
+                    mPutStringMethod.invoke(mActualMetadataEditor, key, value);
+                } catch (Exception e) {
+                    throw new RuntimeException(e.getMessage(), e);
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Sets the album / artwork picture to be displayed on the remote control.
+         * @param key the identifier of the bitmap to set. The only valid value is
+         *      {@link #METADATA_KEY_ARTWORK}
+         * @param bitmap The bitmap for the artwork, or null if there isn't any.
+         * @return Returns a reference to the same MetadataEditor object, so you can chain put
+         *      calls together.
+         * @throws IllegalArgumentException
+         * @see android.graphics.Bitmap
+         */
+        public MetadataEditorCompat putBitmap(int key, Bitmap bitmap) {
+            if (sHasRemoteControlAPIs) {
+                try {
+                    mPutBitmapMethod.invoke(mActualMetadataEditor, key, bitmap);
+                } catch (Exception e) {
+                    throw new RuntimeException(e.getMessage(), e);
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Adds numerical information to be displayed.
+         * Note that none of the information added after {@link #apply()} has been called,
+         * will be displayed.
+         * @param key the identifier of a the metadata field to set. Valid values are
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} (with a value
+         *      expressed in milliseconds),
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}.
+         * @param value The long value for the given key
+         * @return Returns a reference to the same MetadataEditor object, so you can chain put
+         *      calls together.
+         * @throws IllegalArgumentException
+         */
+        public MetadataEditorCompat putLong(int key, long value) {
+            if (sHasRemoteControlAPIs) {
+                try {
+                    mPutLongMethod.invoke(mActualMetadataEditor, key, value);
+                } catch (Exception e) {
+                    throw new RuntimeException(e.getMessage(), e);
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Clears all the metadata that has been set since the MetadataEditor instance was
+         * created with {@link android.media.RemoteControlClient#editMetadata(boolean)}.
+         */
+        public void clear() {
+            if (sHasRemoteControlAPIs) {
+                try {
+                    mClearMethod.invoke(mActualMetadataEditor, (Object[]) null);
+                } catch (Exception e) {
+                    throw new RuntimeException(e.getMessage(), e);
+                }
+            }
+        }
+
+        /**
+         * Associates all the metadata that has been set since the MetadataEditor instance was
+         * created with {@link android.media.RemoteControlClient#editMetadata(boolean)}, or since
+         * {@link #clear()} was called, with the RemoteControlClient. Once "applied", this
+         * MetadataEditor cannot be reused to edit the RemoteControlClient's metadata.
+         */
+        public void apply() {
+            if (sHasRemoteControlAPIs) {
+                try {
+                    mApplyMethod.invoke(mActualMetadataEditor, (Object[]) null);
+                } catch (Exception e) {
+                    throw new RuntimeException(e.getMessage(), e);
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates a {@link android.media.RemoteControlClient.MetadataEditor}.
+     * @param startEmpty Set to false if you want the MetadataEditor to contain the metadata that
+     *     was previously applied to the RemoteControlClient, or true if it is to be created empty.
+     * @return a new MetadataEditor instance.
+     */
+    public MetadataEditorCompat editMetadata(boolean startEmpty) {
+        Object metadataEditor;
+        if (sHasRemoteControlAPIs) {
+            try {
+                metadataEditor = sRCCEditMetadataMethod.invoke(mActualRemoteControlClient,
+                        startEmpty);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        } else {
+            metadataEditor = null;
+        }
+        return new MetadataEditorCompat(metadataEditor);
+    }
+
+    /**
+     * Sets the current playback state.
+     * @param state The current playback state, one of the following values:
+     *       {@link android.media.RemoteControlClient#PLAYSTATE_STOPPED},
+     *       {@link android.media.RemoteControlClient#PLAYSTATE_PAUSED},
+     *       {@link android.media.RemoteControlClient#PLAYSTATE_PLAYING},
+     *       {@link android.media.RemoteControlClient#PLAYSTATE_FAST_FORWARDING},
+     *       {@link android.media.RemoteControlClient#PLAYSTATE_REWINDING},
+     *       {@link android.media.RemoteControlClient#PLAYSTATE_SKIPPING_FORWARDS},
+     *       {@link android.media.RemoteControlClient#PLAYSTATE_SKIPPING_BACKWARDS},
+     *       {@link android.media.RemoteControlClient#PLAYSTATE_BUFFERING},
+     *       {@link android.media.RemoteControlClient#PLAYSTATE_ERROR}.
+     */
+    public void setPlaybackState(int state) {
+        if (sHasRemoteControlAPIs) {
+            try {
+                sRCCSetPlayStateMethod.invoke(mActualRemoteControlClient, state);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * Sets the flags for the media transport control buttons that this client supports.
+     * @param transportControlFlags A combination of the following flags:
+     *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PREVIOUS},
+     *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_REWIND},
+     *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY},
+     *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PLAY_PAUSE},
+     *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_PAUSE},
+     *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_STOP},
+     *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_FAST_FORWARD},
+     *      {@link android.media.RemoteControlClient#FLAG_KEY_MEDIA_NEXT}
+     */
+    public void setTransportControlFlags(int transportControlFlags) {
+        if (sHasRemoteControlAPIs) {
+            try {
+                sRCCSetTransportControlFlags.invoke(mActualRemoteControlClient,
+                        transportControlFlags);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    public final Object getActualRemoteControlClientObject() {
+        return mActualRemoteControlClient;
+    }
+}
diff --git a/samples/RandomMusicPlayer/src/com/example/android/musicplayer/RemoteControlHelper.java b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/RemoteControlHelper.java
new file mode 100644
index 0000000..714d3c5
--- /dev/null
+++ b/samples/RandomMusicPlayer/src/com/example/android/musicplayer/RemoteControlHelper.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.musicplayer;
+
+import android.media.AudioManager;
+import android.util.Log;
+
+import java.lang.reflect.Method;
+
+/**
+ * Contains methods to handle registering/unregistering remote control clients.  These methods only
+ * run on ICS devices.  On previous devices, all methods are no-ops.
+ */
+@SuppressWarnings({"unchecked", "rawtypes"})
+public class RemoteControlHelper {
+    private static final String TAG = "RemoteControlHelper";
+
+    private static boolean sHasRemoteControlAPIs = false;
+
+    private static Method sRegisterRemoteControlClientMethod;
+    private static Method sUnregisterRemoteControlClientMethod;
+
+    static {
+        try {
+            ClassLoader classLoader = RemoteControlHelper.class.getClassLoader();
+            Class sRemoteControlClientClass =
+                    RemoteControlClientCompat.getActualRemoteControlClientClass(classLoader);
+            sRegisterRemoteControlClientMethod = AudioManager.class.getMethod(
+                    "registerRemoteControlClient", new Class[]{sRemoteControlClientClass});
+            sUnregisterRemoteControlClientMethod = AudioManager.class.getMethod(
+                    "unregisterRemoteControlClient", new Class[]{sRemoteControlClientClass});
+            sHasRemoteControlAPIs = true;
+        } catch (ClassNotFoundException e) {
+            // Silently fail when running on an OS before ICS.
+        } catch (NoSuchMethodException e) {
+            // Silently fail when running on an OS before ICS.
+        } catch (IllegalArgumentException e) {
+            // Silently fail when running on an OS before ICS.
+        } catch (SecurityException e) {
+            // Silently fail when running on an OS before ICS.
+        }
+    }
+
+    public static void registerRemoteControlClient(AudioManager audioManager,
+            RemoteControlClientCompat remoteControlClient) {
+        if (!sHasRemoteControlAPIs) {
+            return;
+        }
+
+        try {
+            sRegisterRemoteControlClientMethod.invoke(audioManager,
+                    remoteControlClient.getActualRemoteControlClientObject());
+        } catch (Exception e) {
+            Log.e(TAG, e.getMessage(), e);
+        }
+    }
+
+
+    public static void unregisterRemoteControlClient(AudioManager audioManager,
+            RemoteControlClientCompat remoteControlClient) {
+        if (!sHasRemoteControlAPIs) {
+            return;
+        }
+
+        try {
+            sUnregisterRemoteControlClientMethod.invoke(audioManager,
+                    remoteControlClient.getActualRemoteControlClientObject());
+        } catch (Exception e) {
+            Log.e(TAG, e.getMessage(), e);
+        }
+    }
+}
+
diff --git a/samples/RenderScript/Balls/AndroidManifest.xml b/samples/RenderScript/Balls/AndroidManifest.xml
index c0ae2ff..80e6b39 100644
--- a/samples/RenderScript/Balls/AndroidManifest.xml
+++ b/samples/RenderScript/Balls/AndroidManifest.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.rs.balls">
-    <uses-sdk android:minSdkVersion="11" />
+    <uses-sdk android:minSdkVersion="14" />
     <application 
         android:label="RsBalls"
         android:icon="@drawable/test_pattern">
diff --git a/samples/SampleSpellCheckerService/Android.mk b/samples/SampleSpellCheckerService/Android.mk
new file mode 100755
index 0000000..adf65d9
--- /dev/null
+++ b/samples/SampleSpellCheckerService/Android.mk
@@ -0,0 +1,12 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_SDK_VERSION := current
+
+LOCAL_PACKAGE_NAME := SampleSpellChecker
+
+include $(BUILD_PACKAGE)
diff --git a/samples/SampleSpellCheckerService/AndroidManifest.xml b/samples/SampleSpellCheckerService/AndroidManifest.xml
new file mode 100644
index 0000000..fcb1671
--- /dev/null
+++ b/samples/SampleSpellCheckerService/AndroidManifest.xml
@@ -0,0 +1,47 @@
+<?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.example.android.samplespellcheckerservice" >
+
+    <uses-sdk android:minSdkVersion="14"/>
+    <application
+        android:label="@string/app_name" >
+        <service
+            android:label="@string/app_name"
+            android:name=".SampleSpellCheckerService"
+            android:permission="android.permission.BIND_TEXT_SERVICE" >
+            <intent-filter >
+                <action android:name="android.service.textservice.SpellCheckerService" />
+            </intent-filter>
+
+            <meta-data
+                android:name="android.view.textservice.scs"
+                android:resource="@xml/spellchecker" />
+        </service>
+
+        <activity
+            android:label="@string/sample_settings"
+            android:name="SpellCheckerSettingsActivity" >
+            <intent-filter >
+                <action android:name="android.intent.action.MAIN" />
+            </intent-filter>
+        </activity>
+    </application>
+
+</manifest>
diff --git a/samples/SampleSpellCheckerService/_index.html b/samples/SampleSpellCheckerService/_index.html
new file mode 100755
index 0000000..d6dada9
--- /dev/null
+++ b/samples/SampleSpellCheckerService/_index.html
@@ -0,0 +1,5 @@
+<p>A sample showing how to create a spell checker with the <code><a
+href="../../../reference/android/service/textservice/SpellCheckerService.html">SpellCheckerService</a></code>
+APIs introduced in Android 4.0 (API level 14).</p>
+<p>This app does not have a launcher activity. Once you install it, go to the system's input settings and enable
+"Sample correction" as the spelling correction service. </p>
diff --git a/samples/SampleSpellCheckerService/res/values/strings.xml b/samples/SampleSpellCheckerService/res/values/strings.xml
new file mode 100644
index 0000000..79da5c6
--- /dev/null
+++ b/samples/SampleSpellCheckerService/res/values/strings.xml
@@ -0,0 +1,25 @@
+<?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>
+    <string name="app_name">SampleSpellCheckerService</string>
+    <string name="spellchecker_name">Sample correction</string>
+    <string name="subtype_generic" translatable="false">%s</string>
+    <string name="sample_settings">Sample settings</string>
+    <string name="sample_preference">Sample preference</string>
+</resources>
\ No newline at end of file
diff --git a/samples/SampleSyncAdapter/res/values/styles.xml b/samples/SampleSpellCheckerService/res/xml/spell_checker_settings.xml
similarity index 61%
copy from samples/SampleSyncAdapter/res/values/styles.xml
copy to samples/SampleSpellCheckerService/res/xml/spell_checker_settings.xml
index 074613e..e04d50e 100644
--- a/samples/SampleSyncAdapter/res/values/styles.xml
+++ b/samples/SampleSpellCheckerService/res/xml/spell_checker_settings.xml
@@ -14,14 +14,11 @@
      limitations under the License.
 -->
 
-<resources>
-    <!--
-        These styles will only be used in Honeycomb and later because
-        Android doesn't support third-party contact editing in pre-
-        Honeycomb versions.
-    -->
-    <color name="EditPanelBackgroundColor">#ffffff</color>
-    <color name="EditPanelBorderColor">#cccccc</color>
-    <style name="ContactEditTheme" parent="android:Theme.Holo.Light">
-    </style>
-</resources>
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:title="@string/sample_settings">
+  <CheckBoxPreference
+     android:title="@string/sample_preference"
+     android:persistent="true"
+     android:defaultValue="true" />
+</PreferenceScreen>
diff --git a/samples/SampleSpellCheckerService/res/xml/spellchecker.xml b/samples/SampleSpellCheckerService/res/xml/spellchecker.xml
new file mode 100644
index 0000000..f4601d2
--- /dev/null
+++ b/samples/SampleSpellCheckerService/res/xml/spellchecker.xml
@@ -0,0 +1,30 @@
+<?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.
+ */
+-->
+
+<!-- The attributes in this XML file provide the configuration information -->
+<!-- for the spell checker -->
+
+<spell-checker xmlns:android="http://schemas.android.com/apk/res/android"
+        android:label="@string/spellchecker_name"
+        android:settingsActivity="com.example.android.samplespellcheckerservice.SpellCheckerSettingsActivity">
+    <subtype
+            android:label="@string/subtype_generic"
+            android:subtypeLocale="en"
+    />
+</spell-checker>
diff --git a/samples/SampleSpellCheckerService/src/com/example/android/samplespellcheckerservice/SampleSpellCheckerService.java b/samples/SampleSpellCheckerService/src/com/example/android/samplespellcheckerservice/SampleSpellCheckerService.java
new file mode 100644
index 0000000..dc85587
--- /dev/null
+++ b/samples/SampleSpellCheckerService/src/com/example/android/samplespellcheckerservice/SampleSpellCheckerService.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.samplespellcheckerservice;
+
+import android.service.textservice.SpellCheckerService;
+import android.util.Log;
+import android.view.textservice.SuggestionsInfo;
+import android.view.textservice.TextInfo;
+
+public class SampleSpellCheckerService extends SpellCheckerService {
+    private static final String TAG = SampleSpellCheckerService.class.getSimpleName();
+    private static final boolean DBG = true;
+    @Override
+    public Session createSession() {
+        return new AndroidSpellCheckerSession();
+    }
+
+    private static class AndroidSpellCheckerSession extends Session {
+        private String mLocale;
+        @Override
+        public void onCreate() {
+            mLocale = getLocale();
+        }
+
+        @Override
+        public SuggestionsInfo onGetSuggestions(TextInfo textInfo, int suggestionsLimit) {
+            if (DBG) {
+                Log.d(TAG, "onGetSuggestions: " + textInfo.getText());
+            }
+            final String input = textInfo.getText();
+            final int length = input.length();
+            // Just a fake logic:
+            // length <= 3 for short words that we assume are in the fake dictionary
+            // length > 20 for too long words that we assume can't be recognized (such as CJK words)
+            final int flags = length <= 3 ? SuggestionsInfo.RESULT_ATTR_IN_THE_DICTIONARY
+                    : length <= 20 ? SuggestionsInfo.RESULT_ATTR_LOOKS_LIKE_TYPO : 0;
+            return new SuggestionsInfo(flags,
+                    new String[] {"aaa", "bbb", "Candidate for " + input, mLocale});
+        }
+    }
+}
diff --git a/samples/SampleSpellCheckerService/src/com/example/android/samplespellcheckerservice/SpellCheckerSettingsActivity.java b/samples/SampleSpellCheckerService/src/com/example/android/samplespellcheckerservice/SpellCheckerSettingsActivity.java
new file mode 100644
index 0000000..f223ef7
--- /dev/null
+++ b/samples/SampleSpellCheckerService/src/com/example/android/samplespellcheckerservice/SpellCheckerSettingsActivity.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.example.android.samplespellcheckerservice;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+
+/**
+ * Spell checker preference screen.
+ */
+public class SpellCheckerSettingsActivity extends PreferenceActivity {
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+    }
+
+    @Override
+    public Intent getIntent() {
+        final Intent modIntent = new Intent(super.getIntent());
+        modIntent.putExtra(EXTRA_SHOW_FRAGMENT, SpellCheckerSettingsFragment.class.getName());
+        modIntent.putExtra(EXTRA_NO_HEADERS, true);
+        return modIntent;
+    }
+}
diff --git a/samples/SampleSpellCheckerService/src/com/example/android/samplespellcheckerservice/SpellCheckerSettingsFragment.java b/samples/SampleSpellCheckerService/src/com/example/android/samplespellcheckerservice/SpellCheckerSettingsFragment.java
new file mode 100644
index 0000000..cd2efcc
--- /dev/null
+++ b/samples/SampleSpellCheckerService/src/com/example/android/samplespellcheckerservice/SpellCheckerSettingsFragment.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy
+ * of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.example.android.samplespellcheckerservice;
+
+import android.os.Bundle;
+import android.preference.PreferenceFragment;
+
+/**
+ * Preference screen.
+ */
+public class SpellCheckerSettingsFragment extends PreferenceFragment {
+
+    /**
+     * Empty constructor for fragment generation.
+     */
+    public SpellCheckerSettingsFragment() {
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        addPreferencesFromResource(R.xml.spell_checker_settings);
+    }
+}
diff --git a/samples/SampleSyncAdapter/AndroidManifest.xml b/samples/SampleSyncAdapter/AndroidManifest.xml
index 25e9e99..285abfb 100644
--- a/samples/SampleSyncAdapter/AndroidManifest.xml
+++ b/samples/SampleSyncAdapter/AndroidManifest.xml
@@ -46,7 +46,7 @@
     <uses-permission
         android:name="android.permission.WRITE_SYNC_SETTINGS" />
 
-    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="11"/>
+    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="14"/>
 
     <application
         android:icon="@drawable/icon"
@@ -100,27 +100,8 @@
         </activity>
 
         <activity
-            android:name=".editor.ContactEditorActivity"
-            android:theme="@style/ContactEditTheme"
-            android:windowSoftInputMode="adjustResize">
-            <intent-filter>
-                <action
-                    android:name="android.intent.action.INSERT" />
-                <data
-                    android:mimeType="vnd.android.cursor.item/contact" />
-            </intent-filter>
-
-            <!--
-                Note that the editor gets a raw contact URI, but is expected to call
-                setResult with the corresponding aggregate contact URI, not raw contact
-                URI.
-            -->
-            <intent-filter>
-                <action
-                    android:name="android.intent.action.EDIT" />
-                <data
-                    android:mimeType="vnd.android.cursor.item/raw_contact" />
-            </intent-filter>
+            android:name=".activites.InviteContactActivity"
+            android:theme="@android:style/Theme.Dialog">
             <!--
                 We use the INVITE intent to add a raw contact to an existing contact.
                 It always comes with a lookup URI.
@@ -132,5 +113,50 @@
                     android:mimeType="vnd.android.cursor.item/contact" />
             </intent-filter>
         </activity>
+
+        <activity
+            android:name=".activities.ViewGroupActivity"
+            android:theme="@android:style/Theme.Dialog">
+            <!--
+                We use the VIEW intent to view a group in our app.
+                It always comes with a lookup URI.
+            -->
+            <intent-filter>
+                <action
+                    android:name="android.intent.action.VIEW" />
+                <data
+                    android:mimeType="vnd.android.cursor.item/group" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:name=".activities.ViewStreamItemActivity"
+            android:theme="@android:style/Theme.Dialog">
+            <!--
+                We use the VIEW intent to view a stream item in our app.
+                It always comes with a lookup URI.
+            -->
+            <intent-filter>
+                <action
+                    android:name="android.intent.action.VIEW" />
+                <data
+                    android:mimeType="vnd.android.cursor.item/stream_item" />
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:name=".activities.ViewStreamItemPhotoActivity"
+            android:theme="@android:style/Theme.Dialog">
+            <!--
+                We use the VIEW intent to view a stream item photo in our app.
+                It always comes with a lookup URI.
+            -->
+            <intent-filter>
+                <action
+                    android:name="android.intent.action.VIEW" />
+                <data
+                    android:mimeType="vnd.android.cursor.item/stream_item_photo" />
+            </intent-filter>
+        </activity>
     </application>
 </manifest>
diff --git a/samples/SampleSyncAdapter/res/drawable/border.xml b/samples/SampleSyncAdapter/res/drawable/border.xml
deleted file mode 100644
index ab71f2c..0000000
--- a/samples/SampleSyncAdapter/res/drawable/border.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
-  <solid android:color="@color/EditPanelBackgroundColor" />
-  <stroke android:width="2dip" android:color="@color/EditPanelBorderColor" />
-  <padding android:left="5dip" android:top="5dip" android:right="5dip" android:bottom="5dip" />
-</shape>
\ No newline at end of file
diff --git a/samples/SampleSyncAdapter/res/drawable/done_menu_icon.png b/samples/SampleSyncAdapter/res/drawable/done_menu_icon.png
deleted file mode 100644
index 3468bbd..0000000
--- a/samples/SampleSyncAdapter/res/drawable/done_menu_icon.png
+++ /dev/null
Binary files differ
diff --git a/samples/SampleSyncAdapter/res/layout-xlarge/editor.xml b/samples/SampleSyncAdapter/res/layout-xlarge/editor.xml
deleted file mode 100644
index 3b7d97b..0000000
--- a/samples/SampleSyncAdapter/res/layout-xlarge/editor.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!--
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:gravity="center_horizontal">
-    <LinearLayout
-      xmlns:android="http://schemas.android.com/apk/res/android"
-      android:layout_width="600dip"
-      android:layout_height="match_parent"
-      android:orientation="vertical"
-      android:background="@drawable/border">
-      <include layout="@layout/editor_header" />
-      <ScrollView
-          android:layout_width="match_parent"
-          android:layout_height="0dip"
-          android:paddingTop="20dip"
-          android:paddingRight="20dip"
-          android:paddingBottom="20dip"
-          android:paddingLeft="20dip"
-          android:layout_weight="1">
-          <include layout="@layout/editor_fields" />
-      </ScrollView>
-    </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/samples/SampleSyncAdapter/res/layout-xlarge/editor_header.xml b/samples/SampleSyncAdapter/res/layout-xlarge/editor_header.xml
deleted file mode 100644
index 648e6f9..0000000
--- a/samples/SampleSyncAdapter/res/layout-xlarge/editor_header.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-
-<!-- Account info header -->
-<RelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_height="64dip"
-    android:layout_width="match_parent"
-    android:background="?android:attr/selectableItemBackground">
-
-    <ImageView
-        android:id="@+id/header_account_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_marginLeft="7dip"
-        android:layout_marginRight="7dip"
-        android:layout_centerVertical="true"
-        android:layout_alignParentRight="true"
-        android:src="@drawable/icon" />
-
-    <TextView
-        android:id="@+id/header_account_type"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_toLeftOf="@+id/header_account_icon"
-        android:layout_alignTop="@id/header_account_icon"
-        android:layout_marginTop="-4dip"
-        android:textSize="24sp"
-        android:textColor="?android:attr/textColorPrimary"
-        android:singleLine="true"
-        android:text="@string/header_account_type" />
-
-    <TextView
-        android:id="@+id/header_account_name"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_toLeftOf="@+id/header_account_icon"
-        android:layout_alignBottom="@+id/header_account_icon"
-        android:layout_marginBottom="2dip"
-        android:textAppearance="?android:attr/textAppearanceSmall"
-        android:textColor="?android:attr/textColorPrimary"
-        android:singleLine="true" />
-
-</RelativeLayout>
diff --git a/samples/SampleSyncAdapter/res/layout/editor_fields.xml b/samples/SampleSyncAdapter/res/layout/editor_fields.xml
deleted file mode 100644
index 31d0128..0000000
--- a/samples/SampleSyncAdapter/res/layout/editor_fields.xml
+++ /dev/null
@@ -1,127 +0,0 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!--
-/**
- * Copyright (c) 2010, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--->
-
-<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
-  android:layout_width="fill_parent"
-  android:layout_height="fill_parent"
-  android:stretchColumns="2">
-
-  <TableRow>
-    <TextView
-      android:layout_column="1"
-      android:textStyle="bold"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:text="@string/label_name"
-      android:padding="3dip" />
-    <EditText
-      android:layout_column="2"
-      android:id="@+id/editor_name"
-      android:singleLine="true"
-      android:inputType="textPersonName"
-      android:layout_width="fill_parent"
-      android:layout_height="wrap_content"
-      android:minWidth="250dip"
-      android:scrollHorizontally="true"
-      android:capitalize="none"
-      android:textSize="@dimen/contact_name_text_size"
-      android:gravity="fill_horizontal"
-      android:autoText="false" />
-  </TableRow>
-  <TableRow>
-    <TextView
-      android:layout_column="1"
-      android:textStyle="bold"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:text="@string/label_phone_home"
-      android:padding="3dip" />
-    <EditText
-      android:id="@+id/editor_phone_home"
-      android:singleLine="true"
-      android:inputType="phone"
-      android:layout_width="fill_parent"
-      android:layout_height="wrap_content"
-      android:minWidth="250dip"
-      android:scrollHorizontally="true"
-      android:capitalize="none"
-      android:gravity="fill_horizontal"
-      android:autoText="false" />
-  </TableRow>
-  <TableRow>
-    <TextView
-      android:layout_column="1"
-      android:textStyle="bold"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:text="@string/label_phone_mobile"
-      android:padding="3dip" />
-    <EditText
-      android:id="@+id/editor_phone_mobile"
-      android:singleLine="true"
-      android:inputType="phone"
-      android:layout_width="fill_parent"
-      android:layout_height="wrap_content"
-      android:minWidth="250dip"
-      android:scrollHorizontally="true"
-      android:capitalize="none"
-      android:gravity="fill_horizontal"
-      android:autoText="false" />
-  </TableRow>
-  <TableRow>
-    <TextView
-      android:layout_column="1"
-      android:textStyle="bold"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:text="@string/label_phone_work"
-      android:padding="3dip" />
-    <EditText
-      android:id="@+id/editor_phone_work"
-      android:singleLine="true"
-      android:phoneNumber="true"
-      android:autoText="true"
-      android:layout_width="fill_parent"
-      android:layout_height="wrap_content"
-      android:minWidth="250dip"
-      android:scrollHorizontally="true"
-      android:capitalize="none"
-      android:gravity="fill_horizontal" />
-  </TableRow>
-  <TableRow>
-    <TextView
-      android:layout_column="1"
-      android:textStyle="bold"
-      android:layout_width="wrap_content"
-      android:layout_height="wrap_content"
-      android:text="@string/label_email"
-      android:padding="3dip" />
-    <EditText
-      android:id="@+id/editor_email"
-      android:singleLine="true"
-      android:inputType="textEmailAddress"
-      android:layout_width="fill_parent"
-      android:layout_height="wrap_content"
-      android:minWidth="250dip"
-      android:scrollHorizontally="true"
-      android:capitalize="none"
-      android:gravity="fill_horizontal"
-      android:autoText="false" />
-  </TableRow>
-</TableLayout>
diff --git a/samples/SampleSyncAdapter/res/layout/editor.xml b/samples/SampleSyncAdapter/res/layout/invite_contact_activity.xml
similarity index 61%
rename from samples/SampleSyncAdapter/res/layout/editor.xml
rename to samples/SampleSyncAdapter/res/layout/invite_contact_activity.xml
index a0c36d2..1e09d5b 100644
--- a/samples/SampleSyncAdapter/res/layout/editor.xml
+++ b/samples/SampleSyncAdapter/res/layout/invite_contact_activity.xml
@@ -18,19 +18,15 @@
 -->
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-
-    <ScrollView
-        android:layout_width="match_parent"
-        android:layout_height="0dip"
-        android:paddingTop="20dip"
-        android:paddingRight="20dip"
-        android:paddingBottom="20dip"
-        android:paddingLeft="20dip"
-        android:layout_weight="1">
-        <include layout="@layout/editor_fields" />
-    </ScrollView>
-
-</LinearLayout>
\ No newline at end of file
+    android:orientation="vertical"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <TextView
+        android:text="@string/invite_contact_description"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+    <TextView
+        android:id="@+id/invite_contact_uri"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/samples/SampleSyncAdapter/res/layout/login_activity.xml b/samples/SampleSyncAdapter/res/layout/login_activity.xml
index 7408ffe..6c93f90 100644
--- a/samples/SampleSyncAdapter/res/layout/login_activity.xml
+++ b/samples/SampleSyncAdapter/res/layout/login_activity.xml
@@ -55,7 +55,8 @@
                 android:scrollHorizontally="true"
                 android:capitalize="none"
                 android:autoText="false"
-                android:inputType="textEmailAddress" />
+                android:inputType="textEmailAddress"
+                android:text="user" />
             <TextView
                 android:id="@+id/username_fixed"
                 android:textAppearance="?android:attr/textAppearanceSmall"
@@ -81,7 +82,8 @@
                 android:capitalize="none"
                 android:autoText="false"
                 android:password="true"
-                android:inputType="textPassword" />
+                android:inputType="textPassword"
+                android:text="test" />
             <TextView
                 android:id="@+id/message_bottom"
                 android:textAppearance="?android:attr/textAppearanceSmall"
diff --git a/samples/SampleSyncAdapter/res/layout/view_group_activity.xml b/samples/SampleSyncAdapter/res/layout/view_group_activity.xml
new file mode 100644
index 0000000..45212d9
--- /dev/null
+++ b/samples/SampleSyncAdapter/res/layout/view_group_activity.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+/**
+ * Copyright (c) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <TextView
+        android:text="@string/view_group_description"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+    <TextView
+        android:id="@+id/view_group_uri"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/samples/SampleSyncAdapter/res/layout/view_stream_item_activity.xml b/samples/SampleSyncAdapter/res/layout/view_stream_item_activity.xml
new file mode 100644
index 0000000..a04d07f
--- /dev/null
+++ b/samples/SampleSyncAdapter/res/layout/view_stream_item_activity.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+/**
+ * Copyright (c) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <TextView
+        android:text="@string/view_stream_item_description"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+    <TextView
+        android:id="@+id/view_stream_item_uri"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/samples/SampleSyncAdapter/res/layout/view_stream_item_photo_activity.xml b/samples/SampleSyncAdapter/res/layout/view_stream_item_photo_activity.xml
new file mode 100644
index 0000000..ddc09d0
--- /dev/null
+++ b/samples/SampleSyncAdapter/res/layout/view_stream_item_photo_activity.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+/**
+ * Copyright (c) 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+    <TextView
+        android:text="@string/view_stream_item_photo_description"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+    <TextView
+        android:id="@+id/view_stream_item_photo_uri"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+</LinearLayout>
diff --git a/samples/SampleSyncAdapter/res/menu/edit.xml b/samples/SampleSyncAdapter/res/menu/edit.xml
deleted file mode 100644
index 1227584..0000000
--- a/samples/SampleSyncAdapter/res/menu/edit.xml
+++ /dev/null
@@ -1,30 +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.
--->
-
-<menu xmlns:android="http://schemas.android.com/apk/res/android">
-    <item
-        android:id="@+id/menu_done"
-        android:alphabeticShortcut="\n"
-        android:icon="@drawable/done_menu_icon"
-        android:title="@string/menu_done"
-        android:showAsAction="always|withText" />
-
-    <item
-        android:id="@+id/menu_cancel"
-        android:alphabeticShortcut="q"
-        android:title="@string/menu_cancel"
-        android:showAsAction="always|withText" />
-</menu>
diff --git a/samples/SampleSyncAdapter/res/values/strings.xml b/samples/SampleSyncAdapter/res/values/strings.xml
index 7ac95f5..22fe14e 100644
--- a/samples/SampleSyncAdapter/res/values/strings.xml
+++ b/samples/SampleSyncAdapter/res/values/strings.xml
@@ -109,4 +109,34 @@
     <!-- The label of the button to add contact to this contact provider  -->
     <string name="invite_action_label">Add to Sample SyncAdaper</string>
 
+    <!-- The description for the invite contact flow -->
+    <string name="invite_contact_description">Congratulations! The user wants to add the contact
+        to the amazing Sample SyncAdapter social network. If this was a real app, it should now
+        make best efforts to add the contact to this network. This would probably involve
+        looking up the person on the network, inviting if he is not there already and syncing
+        the new contact down.
+
+        Ideally, when the user gets back to the People app, the new contact should already
+        be there, enriching the original contact.
+
+        This is the information we got to lookup the contact:</string>
+
+    <!-- The label of the button to view a group -->
+    <string name="view_group_action_label">Show sample group details</string>
+
+    <!-- The description for the view group button -->
+    <string name="view_group_description">This would now show the details of the group.
+
+        This is the group uri:</string>
+
+    <!-- The description for the view stream item -->
+    <string name="view_stream_item_description">This would now show the details of the stream item.
+
+        This is the uri of the stream item:</string>
+
+    <!-- The description for the view stream item photo -->
+    <string name="view_stream_item_photo_description">This would now show the details of the stream item photo.
+
+        This is the uri of the photo:</string>
+
 </resources>
\ No newline at end of file
diff --git a/samples/SampleSyncAdapter/res/xml-v11/contacts.xml b/samples/SampleSyncAdapter/res/xml-v11/contacts.xml
index 62dfa80..48cf503 100644
--- a/samples/SampleSyncAdapter/res/xml-v11/contacts.xml
+++ b/samples/SampleSyncAdapter/res/xml-v11/contacts.xml
@@ -19,8 +19,6 @@
 
 <ContactsAccountType
     xmlns:android="http://schemas.android.com/apk/res/android"
-    editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
-    createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
 >
 
     <ContactsDataKind
diff --git a/samples/SampleSyncAdapter/res/xml-v14/contacts.xml b/samples/SampleSyncAdapter/res/xml-v14/contacts.xml
index b900c72..48e079a 100644
--- a/samples/SampleSyncAdapter/res/xml-v14/contacts.xml
+++ b/samples/SampleSyncAdapter/res/xml-v14/contacts.xml
@@ -17,18 +17,15 @@
  */
 -->
 
-<!-- This sample doesn't currently support groups or stream items. viewGroupActivity and
-     viewStreamItemActivity and viewStreamItemPhotoActivity or just here for reference -->
 <ContactsAccountType
     xmlns:android="http://schemas.android.com/apk/res/android"
-    editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
-    createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
-    inviteContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
+    inviteContactActivity="com.example.android.samplesync.activities.InviteContactActivity"
     inviteContactActionLabel="@string/invite_action_label"
     viewContactNotifyService="com.example.android.samplesync.notifier.NotifierService"
-    viewGroupActivity="com.example.android.samplesync.viewer.ViewGroupActivity"
-    viewStreamItemActivity="com.example.android.samplesync.viewer.ViewStreamItemActivity"
-    viewStreamItemPhotoActivity="com.example.android.samplesync.viewer.ViewStreamItemPhotoActivity"
+    viewGroupActivity="com.example.android.samplesync.activities.ViewGroupActivity"
+    viewGroupActionLabel="@string/view_group_action_label"
+    viewStreamItemActivity="com.example.android.samplesync.activities.ViewStreamItemActivity"
+    viewStreamItemPhotoActivity="com.example.android.samplesync.activities.ViewStreamItemPhotoActivity"
 >
 
     <ContactsDataKind
diff --git a/samples/SampleSyncAdapter/res/xml/contacts.xml b/samples/SampleSyncAdapter/res/xml/contacts.xml
index b46257d..06ecf6a 100644
--- a/samples/SampleSyncAdapter/res/xml/contacts.xml
+++ b/samples/SampleSyncAdapter/res/xml/contacts.xml
@@ -19,8 +19,6 @@
 
 <ContactsSource
     xmlns:android="http://schemas.android.com/apk/res/android"
-    editContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
-    createContactActivity="com.example.android.samplesync.editor.ContactEditorActivity"
 >
 
     <ContactsDataKind
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/InviteContactActivity.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/InviteContactActivity.java
new file mode 100644
index 0000000..1923fc2
--- /dev/null
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/InviteContactActivity.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.example.android.samplesync.activities;
+
+import com.example.android.samplesync.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+/**
+ * Activity to handle the invite-intent. In a real app, this would look up the user on the network
+ * and either connect ("add as friend", "follow") or invite them to the network
+ */
+public class InviteContactActivity extends Activity {
+    private static final String TAG = "InviteContactActivity";
+
+    private TextView mUriTextView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.invite_contact_activity);
+
+        mUriTextView = (TextView) findViewById(R.id.invite_contact_uri);
+        mUriTextView.setText(getIntent().getDataString());
+    }
+}
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/ViewGroupActivity.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/ViewGroupActivity.java
new file mode 100644
index 0000000..1b32784
--- /dev/null
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/ViewGroupActivity.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.example.android.samplesync.activities;
+
+import com.example.android.samplesync.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+/**
+ * Activity to handle the view-group action. In a real app, this would show a rich view of the
+ * group, like members, updates etc.
+ */
+public class ViewGroupActivity extends Activity {
+    private static final String TAG = "ViewGroupActivity";
+
+    private TextView mUriTextView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.view_group_activity);
+
+        mUriTextView = (TextView) findViewById(R.id.view_group_uri);
+        mUriTextView.setText(getIntent().getDataString());
+    }
+}
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/ViewStreamItemActivity.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/ViewStreamItemActivity.java
new file mode 100644
index 0000000..6d54f31
--- /dev/null
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/ViewStreamItemActivity.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.example.android.samplesync.activities;
+
+import com.example.android.samplesync.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+/**
+ * Activity to handle view a stream-item. In a real app, this would show a rich view of the
+ * item.
+ */
+public class ViewStreamItemActivity extends Activity {
+    private static final String TAG = "ViewStreamItemActivity";
+
+    private TextView mUriTextView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.view_stream_item_activity);
+
+        mUriTextView = (TextView) findViewById(R.id.view_stream_item_uri);
+        mUriTextView.setText(getIntent().getDataString());
+    }
+}
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/ViewStreamItemPhotoActivity.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/ViewStreamItemPhotoActivity.java
new file mode 100644
index 0000000..962bc70
--- /dev/null
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/activities/ViewStreamItemPhotoActivity.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.example.android.samplesync.activities;
+
+import com.example.android.samplesync.R;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+/**
+ * Activity to view a stream-item-photo. In a real app, this would show a fullscreen view of the
+ * photo, potentially with ways to interact with it
+ */
+public class ViewStreamItemPhotoActivity extends Activity {
+    private static final String TAG = "ViewStreamItemPhotoActivity";
+
+    private TextView mUriTextView;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.view_stream_item_photo_activity);
+
+        mUriTextView = (TextView) findViewById(R.id.view_stream_item_photo_uri);
+        mUriTextView.setText(getIntent().getDataString());
+    }
+}
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticatorActivity.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticatorActivity.java
index 2a3c0fc..5649f6d 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticatorActivity.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/authenticator/AuthenticatorActivity.java
@@ -110,7 +110,7 @@
         mMessage = (TextView) findViewById(R.id.message);
         mUsernameEdit = (EditText) findViewById(R.id.username_edit);
         mPasswordEdit = (EditText) findViewById(R.id.password_edit);
-        mUsernameEdit.setText(mUsername);
+        if (!TextUtils.isEmpty(mUsername)) mUsernameEdit.setText(mUsername);
         mMessage.setText(getMessage());
     }
 
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/NetworkUtilities.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/NetworkUtilities.java
index bebcd72..c2ebd19 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/NetworkUtilities.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/client/NetworkUtilities.java
@@ -16,16 +16,6 @@
 
 package com.example.android.samplesync.client;
 
-import android.accounts.Account;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.Handler;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.example.android.samplesync.authenticator.AuthenticatorActivity;
-
 import org.apache.http.HttpEntity;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
@@ -41,9 +31,15 @@
 import org.apache.http.params.HttpConnectionParams;
 import org.apache.http.params.HttpParams;
 import org.apache.http.util.EntityUtils;
-import org.json.JSONObject;
 import org.json.JSONArray;
 import org.json.JSONException;
+import org.json.JSONObject;
+
+import android.accounts.Account;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.text.TextUtils;
+import android.util.Log;
 
 import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
@@ -54,11 +50,8 @@
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
-import java.util.TimeZone;
 
 /**
  * Provides utility methods for communicating with the server.
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/editor/ContactEditorActivity.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/editor/ContactEditorActivity.java
deleted file mode 100644
index efda0cc..0000000
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/editor/ContactEditorActivity.java
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.example.android.samplesync.editor;
-
-import com.example.android.samplesync.Constants;
-import com.example.android.samplesync.R;
-import com.example.android.samplesync.client.RawContact;
-import com.example.android.samplesync.platform.BatchOperation;
-import com.example.android.samplesync.platform.ContactManager;
-import com.example.android.samplesync.platform.ContactManager.ContactQuery;
-import com.example.android.samplesync.platform.ContactManager.EditorQuery;
-
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.Activity;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.AsyncTask;
-import android.os.Bundle;
-import android.provider.ContactsContract;
-import android.provider.ContactsContract.CommonDataKinds.Email;
-import android.provider.ContactsContract.CommonDataKinds.Phone;
-import android.provider.ContactsContract.CommonDataKinds.StructuredName;
-import android.provider.ContactsContract.RawContacts;
-import android.util.Log;
-import android.view.Menu;
-import android.view.MenuInflater;
-import android.view.MenuItem;
-import android.widget.EditText;
-import android.widget.TextView;
-
-/**
- * Implements a sample editor for a contact that belongs to a remote contact service.
- * The editor can be invoked for an existing SampleSyncAdapter contact, or it can
- * be used to create a brand new SampleSyncAdapter contact. We look at the Intent
- * object to figure out whether this is a "new" or "edit" operation.
- */
-public class ContactEditorActivity extends Activity {
-    private static final String TAG = "SampleSyncAdapter";
-
-    // Keep track of whether we're inserting a new contact or editing an
-    // existing contact.
-    private boolean mIsInsert;
-
-    // The name of the external account we're syncing this contact to.
-    private String mAccountName;
-
-    // For existing contacts, this is the URI to the contact data.
-    private Uri mRawContactUri;
-
-    // The raw clientId for this contact
-    private long mRawContactId;
-
-    // Make sure we only attempt to save the contact once if the
-    // user presses the "done" button multiple times...
-    private boolean mSaveInProgress = false;
-
-    // Keep track of the controls used to edit contact values, so we can get/set
-    // those values easily.
-    private EditText mNameEditText;
-    private EditText mHomePhoneEditText;
-    private EditText mMobilePhoneEditText;
-    private EditText mWorkPhoneEditText;
-    private EditText mEmailEditText;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-
-        setContentView(R.layout.editor);
-
-        mNameEditText = (EditText)findViewById(R.id.editor_name);
-        mHomePhoneEditText = (EditText)findViewById(R.id.editor_phone_home);
-        mMobilePhoneEditText = (EditText)findViewById(R.id.editor_phone_mobile);
-        mWorkPhoneEditText = (EditText)findViewById(R.id.editor_phone_work);
-        mEmailEditText = (EditText)findViewById(R.id.editor_email);
-
-        // Figure out whether we're creating a new contact (ACTION_INSERT), editing
-        // an existing contact, or adding a new one to existing contact (INVITE_CONTACT).
-        Intent intent = getIntent();
-        String action = intent.getAction();
-        if (Intent.ACTION_INSERT.equals(action)) {
-            // We're inserting a new contact, so save off the external account name
-            // which should have been added to the intent we were passed.
-            mIsInsert = true;
-            String accountName = intent.getStringExtra(RawContacts.ACCOUNT_NAME);
-            if (accountName == null) {
-                Log.e(TAG, "Account name is required");
-                finish();
-            }
-            setAccountName(accountName);
-        } else if (ContactsContract.Intents.INVITE_CONTACT.equals(action)) {
-            // Adding to an existing contact.
-            mIsInsert = true;
-            // Use the first account found.
-            Account[] myAccounts = AccountManager.get(this).getAccountsByType(
-                    Constants.ACCOUNT_TYPE);
-            if (myAccounts.length == 0) {
-                Log.e(TAG, "Account not configured");
-                finish();
-            }
-            setAccountName(myAccounts[0].name);
-
-            Uri lookupUri = intent.getData();
-            if (lookupUri == null) {
-                Log.e(TAG, "Contact lookup URI is required");
-                finish();
-            }
-            startLoadContactEntity(lookupUri);
-        } else {
-            // We're editing an existing contact. Load in the data from the contact
-            // so that the user can edit it.
-            mIsInsert = false;
-            mRawContactUri = intent.getData();
-            if (mRawContactUri == null) {
-                Log.e(TAG, "Raw contact URI is required");
-                finish();
-            }
-            startLoadRawContactEntity();
-        }
-    }
-
-    @Override
-    public void onBackPressed() {
-        // This method will have been called if the user presses the "Back" button
-        // in the ActionBar.  We treat that the same way as the "Done" button in
-        // the ActionBar.
-        save();
-    }
-
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        // This method gets called so that we can place items in the main Options menu -
-        // for example, the ActionBar items.  We add our menus from the res/menu/edit.xml
-        // file.
-        MenuInflater inflater = getMenuInflater();
-        inflater.inflate(R.menu.edit, menu);
-        return true;
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case android.R.id.home:
-            case R.id.menu_done:
-                // The user pressed the "Home" button or our "Done" button - both
-                // in the ActionBar.  In both cases, we want to save the contact
-                // and exit.
-                save();
-                return true;
-            case R.id.menu_cancel:
-                // The user pressed the Cancel menu item in the ActionBar.
-                // Close the editor without saving any changes.
-                finish();
-                return true;
-        }
-        return false;
-    }
-
-    /**
-     * Create an AsyncTask to load the contact from the Contacts data provider
-     */
-    private void startLoadRawContactEntity() {
-        Uri uri = Uri.withAppendedPath(mRawContactUri, RawContacts.Entity.CONTENT_DIRECTORY);
-        new LoadRawContactTask().execute(uri);
-    }
-
-    /**
-     * Called by the LoadRawContactTask when the contact information has been
-     * successfully loaded from the Contacts data provider.
-     */
-    public void onRawContactEntityLoaded(Cursor cursor) {
-        if (cursor.moveToFirst()) {
-            String mimetype = cursor.getString(EditorQuery.COLUMN_MIMETYPE);
-            if (StructuredName.CONTENT_ITEM_TYPE.equals(mimetype)) {
-                setAccountName(cursor.getString(EditorQuery.COLUMN_ACCOUNT_NAME));
-                mRawContactId = cursor.getLong(EditorQuery.COLUMN_RAW_CONTACT_ID);
-                mNameEditText.setText(cursor.getString(EditorQuery.COLUMN_FULL_NAME));
-            } else if (Phone.CONTENT_ITEM_TYPE.equals(mimetype)) {
-                final int type = cursor.getInt(EditorQuery.COLUMN_PHONE_TYPE);
-                if (type == Phone.TYPE_HOME) {
-                    mHomePhoneEditText.setText(cursor.getString(EditorQuery.COLUMN_PHONE_NUMBER));
-                } else if (type == Phone.TYPE_MOBILE) {
-                    mMobilePhoneEditText.setText(cursor.getString(EditorQuery.COLUMN_PHONE_NUMBER));
-                } else if (type == Phone.TYPE_WORK) {
-                    mWorkPhoneEditText.setText(cursor.getString(EditorQuery.COLUMN_PHONE_NUMBER));
-                }
-            } else if (Email.CONTENT_ITEM_TYPE.equals(mimetype)) {
-                mEmailEditText.setText(cursor.getString(EditorQuery.COLUMN_DATA1));
-            }
-        }
-    }
-
-    /**
-     * Create an AsyncTask to load the contact from the Contacts data provider
-     */
-    private void startLoadContactEntity(Uri lookupUri) {
-        new LoadContactTask().execute(lookupUri);
-    }
-
-    /**
-     * Called by the LoadContactTask when the contact information has been
-     * successfully loaded from the Contacts data provider.
-     */
-    public void onContactEntityLoaded(Cursor cursor) {
-        if (cursor.moveToFirst()) {
-            mNameEditText.setText(cursor.getString(ContactQuery.COLUMN_DISPLAY_NAME));
-        }
-    }
-
-    /**
-     * Save the updated contact data. We actually take two different actions
-     * depending on whether we are creating a new contact or editing an
-     * existing contact.
-     */
-    public void save() {
-        // If we're already saving this contact, don't kick-off yet
-        // another save - the user probably just pressed the "Done"
-        // button multiple times...
-        if (mSaveInProgress) {
-            return;
-        }
-
-        mSaveInProgress = true;
-        if (mIsInsert) {
-            saveNewContact();
-        } else {
-            saveChanges();
-        }
-    }
-
-    /**
-     * Save off the external contacts provider account name. We show the account name
-     * in the header section of the edit panel, and we also need it later when we
-     * save off a brand new contact.
-     */
-    private void setAccountName(String accountName) {
-        mAccountName = accountName;
-        Log.i(TAG, "account=" + mAccountName);
-        if (accountName != null) {
-            TextView accountNameLabel = (TextView)findViewById(R.id.header_account_name);
-            if (accountNameLabel != null) {
-                accountNameLabel.setText(accountName);
-            }
-        }
-    }
-
-    /**
-     * Save a new contact using the Contacts content provider. The actual insertion
-     * is performed in an AsyncTask.
-     */
-    @SuppressWarnings("unchecked")
-    private void saveNewContact() {
-        new InsertContactTask().execute(buildRawContact());
-    }
-
-    /**
-     * Save changes to an existing contact.  The actual update is performed in
-     * an AsyncTask.
-     */
-    @SuppressWarnings("unchecked")
-    private void saveChanges() {
-        new UpdateContactTask().execute(buildRawContact());
-    }
-
-    /**
-     * Build a RawContact object from the data in the user-editable form
-     * @return a new RawContact object representing the edited user
-     */
-    private RawContact buildRawContact() {
-        return RawContact.create(mNameEditText.getText().toString(),
-                null,
-                null,
-                mMobilePhoneEditText.getText().toString(),
-                mWorkPhoneEditText.getText().toString(),
-                mHomePhoneEditText.getText().toString(),
-                mEmailEditText.getText().toString(),
-                null,
-                false,
-                mRawContactId,
-                -1);
-    }
-
-    /**
-     * Called after a contact is saved - both for edited contacts and new contacts.
-     * We set the final result of the activity to be "ok", and then close the activity
-     * by calling finish().
-     */
-    public void onContactSaved(Uri result) {
-        if (result != null) {
-            Intent intent = new Intent();
-            intent.setData(result);
-            setResult(RESULT_OK, intent);
-            finish();
-        }
-        mSaveInProgress = false;
-    }
-
-    /**
-     * Represents an asynchronous task used to load a contact from
-     * the Contacts content provider.
-     *
-     */
-    public class LoadRawContactTask extends AsyncTask<Uri, Void, Cursor> {
-
-        @Override
-        protected Cursor doInBackground(Uri... params) {
-            // Our background task is to load the contact from the Contacts provider
-            return getContentResolver().query(params[0], EditorQuery.PROJECTION, null, null, null);
-        }
-
-        @Override
-        protected void onPostExecute(Cursor cursor) {
-            if (cursor == null) return;
-            // After we've successfully loaded the contact, call back into
-            // the ContactEditorActivity so we can update the UI
-            try {
-                onRawContactEntityLoaded(cursor);
-            } finally {
-                cursor.close();
-            }
-        }
-    }
-
-    /**
-     * Represents an asynchronous task used to save a new contact
-     * into the contacts database.
-     */
-    public class InsertContactTask extends AsyncTask<RawContact, Void, Uri> {
-
-        @Override
-        protected Uri doInBackground(RawContact... params) {
-            try {
-                final RawContact rawContact = params[0];
-                final Context context = getApplicationContext();
-                final ContentResolver resolver = getContentResolver();
-                final BatchOperation batchOperation = new BatchOperation(context, resolver);
-                ContactManager.addContact(context, mAccountName, rawContact, false, batchOperation);
-                Uri rawContactUri = batchOperation.execute();
-
-                // Convert the raw contact URI to a contact URI
-                if (rawContactUri != null) {
-                    return RawContacts.getContactLookupUri(resolver, rawContactUri);
-                } else {
-                    Log.e(TAG, "Could not save new contact");
-                    return null;
-                }
-            } catch (Exception e) {
-                Log.e(TAG, "An error occurred while saving new contact", e);
-            }
-            return null;
-        }
-
-        @Override
-        protected void onPostExecute(Uri result) {
-            // Tell the UI that the contact has been successfully saved
-            onContactSaved(result);
-        }
-    }
-
-
-    /**
-     * Represents an asynchronous task used to save an updated contact
-     * into the contacts database.
-     */
-    public class UpdateContactTask extends AsyncTask<RawContact, Void, Uri> {
-
-        @Override
-        protected Uri doInBackground(RawContact... params) {
-            try {
-                final RawContact rawContact = params[0];
-                final Context context = getApplicationContext();
-                final ContentResolver resolver = getContentResolver();
-                final BatchOperation batchOperation = new BatchOperation(context, resolver);
-                ContactManager.updateContact(context, resolver, rawContact, false, false, false,
-                        false, rawContact.getRawContactId(), batchOperation);
-                batchOperation.execute();
-
-                // Convert the raw contact URI to a contact URI
-                return RawContacts.getContactLookupUri(resolver, mRawContactUri);
-            } catch (Exception e) {
-                Log.e(TAG, "Could not save changes", e);
-            }
-            return null;
-        }
-
-        @Override
-        protected void onPostExecute(Uri result) {
-            // Tell the UI that the contact has been successfully saved
-            onContactSaved(result);
-        }
-    }
-
-    /**
-     * Loads contact information by a lookup URI.
-     */
-    public class LoadContactTask extends AsyncTask<Uri, Void, Cursor> {
-
-        @Override
-        protected Cursor doInBackground(Uri... params) {
-            return getContentResolver().query(params[0], ContactQuery.PROJECTION, null, null, null);
-        }
-
-        @Override
-        protected void onPostExecute(Cursor cursor) {
-            if (cursor == null) return;
-            try {
-                onContactEntityLoaded(cursor);
-            } finally {
-                cursor.close();
-            }
-        }
-    }
-}
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
index 035c976..6b2dfb1 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactManager.java
@@ -34,6 +34,7 @@
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
+import android.provider.ContactsContract.Groups;
 import android.provider.ContactsContract.RawContacts;
 import android.provider.ContactsContract.Settings;
 import android.provider.ContactsContract.StatusUpdates;
@@ -54,6 +55,41 @@
 
     private static final String TAG = "ContactManager";
 
+    public static final String SAMPLE_GROUP_NAME = "Sample Group";
+
+    public static long ensureSampleGroupExists(Context context, Account account) {
+        final ContentResolver resolver = context.getContentResolver();
+
+        // Lookup the sample group
+        long groupId = 0;
+        final Cursor cursor = resolver.query(Groups.CONTENT_URI, new String[] { Groups._ID },
+                Groups.ACCOUNT_NAME + "=? AND " + Groups.ACCOUNT_TYPE + "=? AND " +
+                Groups.TITLE + "=?",
+                new String[] { account.name, account.type, SAMPLE_GROUP_NAME }, null);
+        if (cursor != null) {
+            try {
+                if (cursor.moveToFirst()) {
+                    groupId = cursor.getLong(0);
+                }
+            } finally {
+                cursor.close();
+            }
+        }
+
+        if (groupId == 0) {
+            // Sample group doesn't exist yet, so create it
+            final ContentValues contentValues = new ContentValues();
+            contentValues.put(Groups.ACCOUNT_NAME, account.name);
+            contentValues.put(Groups.ACCOUNT_TYPE, account.type);
+            contentValues.put(Groups.TITLE, SAMPLE_GROUP_NAME);
+            contentValues.put(Groups.GROUP_IS_READ_ONLY, true);
+
+            final Uri newGroupUri = resolver.insert(Groups.CONTENT_URI, contentValues);
+            groupId = ContentUris.parseId(newGroupUri);
+        }
+        return groupId;
+    }
+
     /**
      * Take a list of updated contacts and apply those changes to the
      * contacts database. Typically this list of contacts would have been
@@ -67,7 +103,7 @@
      * sync request.
      */
     public static synchronized long updateContacts(Context context, String account,
-            List<RawContact> rawContacts, long lastSyncMarker) {
+            List<RawContact> rawContacts, long groupId, long lastSyncMarker) {
 
         long currentSyncMarker = lastSyncMarker;
         final ContentResolver resolver = context.getContentResolver();
@@ -112,7 +148,7 @@
                 Log.d(TAG, "In addContact");
                 if (!rawContact.isDeleted()) {
                     newUsers.add(rawContact);
-                    addContact(context, account, rawContact, true, batchOperation);
+                    addContact(context, account, rawContact, groupId, true, batchOperation);
                 }
             }
             // A sync adapter should batch operations on multiple contacts,
@@ -235,12 +271,13 @@
      * @param context the Authenticator Activity context
      * @param accountName the account the contact belongs to
      * @param rawContact the sample SyncAdapter User object
+     * @param groupId the id of the sample group
      * @param inSync is the add part of a client-server sync?
      * @param batchOperation allow us to batch together multiple operations
      *        into a single provider call
      */
     public static void addContact(Context context, String accountName, RawContact rawContact,
-        boolean inSync, BatchOperation batchOperation) {
+            long groupId, boolean inSync, BatchOperation batchOperation) {
 
         // Put the data in the contacts provider
         final ContactOperations contactOp = ContactOperations.createNewContact(
@@ -252,6 +289,7 @@
                 .addPhone(rawContact.getCellPhone(), Phone.TYPE_MOBILE)
                 .addPhone(rawContact.getHomePhone(), Phone.TYPE_HOME)
                 .addPhone(rawContact.getOfficePhone(), Phone.TYPE_WORK)
+                .addGroupMembership(groupId)
                 .addAvatar(rawContact.getAvatarUrl());
 
         // If we have a serverId, then go ahead and create our status profile.
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactOperations.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactOperations.java
index cb8e97b..1445e55 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactOperations.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/platform/ContactOperations.java
@@ -25,6 +25,7 @@
 import android.net.Uri;
 import android.provider.ContactsContract;
 import android.provider.ContactsContract.CommonDataKinds.Email;
+import android.provider.ContactsContract.CommonDataKinds.GroupMembership;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
 import android.provider.ContactsContract.CommonDataKinds.Photo;
 import android.provider.ContactsContract.CommonDataKinds.StructuredName;
@@ -185,6 +186,20 @@
         return this;
     }
 
+    /**
+     * Adds a group membership
+     *
+     * @param id The id of the group to assign
+     * @return instance of ContactOperations
+     */
+    public ContactOperations addGroupMembership(long groupId) {
+        mValues.clear();
+        mValues.put(GroupMembership.GROUP_ROW_ID, groupId);
+        mValues.put(GroupMembership.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
+        addInsertOp();
+        return this;
+    }
+
     public ContactOperations addAvatar(String avatarUrl) {
         if (avatarUrl != null) {
             byte[] avatarBuffer = NetworkUtilities.downloadAvatar(avatarUrl);
diff --git a/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncAdapter.java b/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncAdapter.java
index 0ca8dee..0f570cd 100644
--- a/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncAdapter.java
+++ b/samples/SampleSyncAdapter/src/com/example/android/samplesync/syncadapter/SyncAdapter.java
@@ -15,6 +15,15 @@
  */
 package com.example.android.samplesync.syncadapter;
 
+import com.example.android.samplesync.Constants;
+import com.example.android.samplesync.client.NetworkUtilities;
+import com.example.android.samplesync.client.RawContact;
+import com.example.android.samplesync.platform.ContactManager;
+
+import org.apache.http.ParseException;
+import org.apache.http.auth.AuthenticationException;
+import org.json.JSONException;
+
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.AuthenticatorException;
@@ -27,18 +36,7 @@
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.example.android.samplesync.Constants;
-import com.example.android.samplesync.client.NetworkUtilities;
-import com.example.android.samplesync.client.RawContact;
-import com.example.android.samplesync.platform.ContactManager;
-
-import org.apache.http.ParseException;
-import org.apache.http.auth.AuthenticationException;
-import org.json.JSONException;
-
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
 import java.util.List;
 
 /**
@@ -91,6 +89,9 @@
             final String authtoken = mAccountManager.blockingGetAuthToken(account,
                     Constants.AUTHTOKEN_TYPE, NOTIFY_AUTH_FAILURE);
 
+            // Make sure that the sample group exists
+            final long groupId = ContactManager.ensureSampleGroupExists(mContext, account);
+
             // Find the local 'dirty' contacts that we need to tell the server about...
             // Find the local users that need to be sync'd to the server...
             dirtyContacts = ContactManager.getDirtyContacts(mContext, account);
@@ -106,6 +107,7 @@
             long newSyncState = ContactManager.updateContacts(mContext,
                     account.name,
                     updatedContacts,
+                    groupId,
                     lastSyncMarker);
 
             // This is a demo of how you can update IM-style status messages
diff --git a/samples/StackWidget/AndroidManifest.xml b/samples/StackWidget/AndroidManifest.xml
index 1fec157..25517f0 100644
--- a/samples/StackWidget/AndroidManifest.xml
+++ b/samples/StackWidget/AndroidManifest.xml
@@ -22,7 +22,7 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.stackwidget">
-    <uses-sdk android:targetSdkVersion="11" android:minSdkVersion="11"/>
+    <uses-sdk android:targetSdkVersion="14" android:minSdkVersion="11"/>
     <application android:label="StackWidget">
         <receiver android:name="StackWidgetProvider">
             <intent-filter>
diff --git a/samples/StackWidget/res/layout/widget_layout.xml b/samples/StackWidget/res/layout/widget_layout.xml
index 11f9d36..983c6fb 100644
--- a/samples/StackWidget/res/layout/widget_layout.xml
+++ b/samples/StackWidget/res/layout/widget_layout.xml
@@ -15,7 +15,8 @@
 -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:layout_margin="@dimen/widget_margin">
     <StackView xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/stack_view"
         android:layout_width="match_parent"
diff --git a/samples/SampleSyncAdapter/res/values/styles.xml b/samples/StackWidget/res/values-v14/dimens.xml
similarity index 64%
rename from samples/SampleSyncAdapter/res/values/styles.xml
rename to samples/StackWidget/res/values-v14/dimens.xml
index 074613e..2626bc3 100644
--- a/samples/SampleSyncAdapter/res/values/styles.xml
+++ b/samples/StackWidget/res/values-v14/dimens.xml
@@ -13,15 +13,6 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <resources>
-    <!--
-        These styles will only be used in Honeycomb and later because
-        Android doesn't support third-party contact editing in pre-
-        Honeycomb versions.
-    -->
-    <color name="EditPanelBackgroundColor">#ffffff</color>
-    <color name="EditPanelBorderColor">#cccccc</color>
-    <style name="ContactEditTheme" parent="android:Theme.Holo.Light">
-    </style>
+    <dimen name="widget_margin">0dp</dimen>
 </resources>
diff --git a/samples/SampleSyncAdapter/res/values/styles.xml b/samples/StackWidget/res/values/dimens.xml
similarity index 64%
copy from samples/SampleSyncAdapter/res/values/styles.xml
copy to samples/StackWidget/res/values/dimens.xml
index 074613e..aa8a9e2 100644
--- a/samples/SampleSyncAdapter/res/values/styles.xml
+++ b/samples/StackWidget/res/values/dimens.xml
@@ -13,15 +13,6 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <resources>
-    <!--
-        These styles will only be used in Honeycomb and later because
-        Android doesn't support third-party contact editing in pre-
-        Honeycomb versions.
-    -->
-    <color name="EditPanelBackgroundColor">#ffffff</color>
-    <color name="EditPanelBorderColor">#cccccc</color>
-    <style name="ContactEditTheme" parent="android:Theme.Holo.Light">
-    </style>
+    <dimen name="widget_margin">8dp</dimen>
 </resources>
diff --git a/samples/StackWidget/res/xml/stackwidgetinfo.xml b/samples/StackWidget/res/xml/stackwidgetinfo.xml
index 6f59605..2a587e1 100644
--- a/samples/StackWidget/res/xml/stackwidgetinfo.xml
+++ b/samples/StackWidget/res/xml/stackwidgetinfo.xml
@@ -15,11 +15,13 @@
 -->
 <appwidget-provider
   xmlns:android="http://schemas.android.com/apk/res/android"
-  android:minWidth="150dip"
-  android:minHeight="150dip"
+  android:minWidth="110dip"
+  android:minHeight="110dip"
   android:updatePeriodMillis="3600000"
   android:previewImage="@drawable/preview"
   android:initialLayout="@layout/widget_layout"
-  android:autoAdvanceViewId="@id/stack_view"
-  android:resizeMode="horizontal|vertical">
+  android:autoAdvanceViewId="@id/stack_view">
 </appwidget-provider>
+<!--to enable resizing:
+ android:resizeMode="horizontal|vertical" -->
+ 
\ No newline at end of file
diff --git a/samples/VoicemailProviderDemo/src/com/example/android/voicemail/AddVoicemailActivity.java b/samples/VoicemailProviderDemo/src/com/example/android/voicemail/AddVoicemailActivity.java
index 121840a..2adb0c4 100644
--- a/samples/VoicemailProviderDemo/src/com/example/android/voicemail/AddVoicemailActivity.java
+++ b/samples/VoicemailProviderDemo/src/com/example/android/voicemail/AddVoicemailActivity.java
@@ -206,13 +206,10 @@
             Uri newVoicemailUri = mVoicemailProviderHelper.insert(voicemail);
             logger.i("Inserted new voicemail URI: " + newVoicemailUri);
             if (inputAudioStream != null) {
-                OutputStream outputStream = null;
                 try {
-                    outputStream = mVoicemailProviderHelper.setVoicemailContent(
-                            newVoicemailUri, getContentResolver().getType(recordingUri));
-                    copyStreamData(inputAudioStream, outputStream);
+                    mVoicemailProviderHelper.setVoicemailContent(newVoicemailUri, inputAudioStream,
+                            getContentResolver().getType(recordingUri));
                 } finally {
-                    CloseUtils.closeQuietly(outputStream);
                     CloseUtils.closeQuietly(inputAudioStream);
                 }
             }
@@ -228,13 +225,5 @@
             }
         }
 
-        private void copyStreamData(InputStream in, OutputStream out) throws IOException {
-            // Copy 8K chunk at a time.
-            byte[] data = new byte[8 * 1024];
-            int numBytes;
-            while ((numBytes = in.read(data)) > 0) {
-                out.write(data, 0, numBytes);
-            }
-        }
     }
 }
diff --git a/samples/VoicemailProviderDemo/src/com/example/android/voicemail/common/core/VoicemailProviderHelper.java b/samples/VoicemailProviderDemo/src/com/example/android/voicemail/common/core/VoicemailProviderHelper.java
index 9cb6a3b..918aa4a 100644
--- a/samples/VoicemailProviderDemo/src/com/example/android/voicemail/common/core/VoicemailProviderHelper.java
+++ b/samples/VoicemailProviderDemo/src/com/example/android/voicemail/common/core/VoicemailProviderHelper.java
@@ -21,7 +21,7 @@
 import android.net.Uri;
 
 import java.io.IOException;
-import java.io.OutputStream;
+import java.io.InputStream;
 import java.util.List;
 
 /**
@@ -99,14 +99,25 @@
     public int update(Uri uri, Voicemail voicemail);
 
     /**
-     * Get the OutputStream to write the voicemail content with the given mime type.
+     * Sets the voicemail content from the supplied input stream.
      * <p>
-     * <b>Remember to close the OutputStream after you're done writing.</b>
+     * The inputStream is owned by the caller and must be closed by it as usual after the call has
+     * returned.
      *
      * @throws IOException if there is a problem creating the file or no voicemail is found matching
      *             the given Uri
      */
-    public OutputStream setVoicemailContent(Uri voicemailUri, String mimeType) throws IOException;
+    public void setVoicemailContent(Uri voicemailUri, InputStream inputStream, String mimeType)
+            throws IOException;
+
+    /**
+     * Sets the voicemail content from the supplied byte array.
+     *
+     * @throws IOException if there is a problem creating the file or no voicemail is found matching
+     *             the given Uri
+     */
+    public void setVoicemailContent(Uri voicemailUri, byte[] inputBytes, String mimeType)
+            throws IOException;
 
     /**
      * Fetch all the voicemails accessible to this voicemail content provider.
diff --git a/samples/VoicemailProviderDemo/src/com/example/android/voicemail/common/core/VoicemailProviderHelpers.java b/samples/VoicemailProviderDemo/src/com/example/android/voicemail/common/core/VoicemailProviderHelpers.java
index 1840462..27c7f69 100644
--- a/samples/VoicemailProviderDemo/src/com/example/android/voicemail/common/core/VoicemailProviderHelpers.java
+++ b/samples/VoicemailProviderDemo/src/com/example/android/voicemail/common/core/VoicemailProviderHelpers.java
@@ -30,6 +30,7 @@
 import android.provider.VoicemailContract.Voicemails;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
@@ -114,16 +115,45 @@
     }
 
     @Override
-    public OutputStream setVoicemailContent(Uri voicemailUri, String mimeType) throws IOException {
+    public void setVoicemailContent(Uri voicemailUri, InputStream inputStream, String mimeType)
+            throws IOException {
+        setVoicemailContent(voicemailUri, null, inputStream, mimeType);
+    }
+
+    @Override
+    public void setVoicemailContent(Uri voicemailUri, byte[] inputBytes, String mimeType)
+            throws IOException {
+        setVoicemailContent(voicemailUri, inputBytes, null, mimeType);
+    }
+
+    private void setVoicemailContent(Uri voicemailUri, byte[] inputBytes, InputStream inputStream,
+            String mimeType) throws IOException {
+        if (inputBytes != null && inputStream != null) {
+            throw new IllegalArgumentException("Both inputBytes & inputStream non-null. Don't" +
+                    " know which one to use.");
+        }
+
+        logger.d(String.format("Writing new voicemail content: %s", voicemailUri));
+        OutputStream outputStream = null;
+        try {
+            outputStream = mContentResolver.openOutputStream(voicemailUri);
+            if (inputBytes != null) {
+                outputStream.write(inputBytes);
+            } else if (inputStream != null) {
+                copyStreamData(inputStream, outputStream);
+            }
+        } finally {
+            CloseUtils.closeQuietly(outputStream);
+        }
+        // Update mime_type & has_content after we are done with file update.
         ContentValues values = new ContentValues();
         values.put(Voicemails.MIME_TYPE, mimeType);
+        values.put(Voicemails.HAS_CONTENT, true);
         int updatedCount = mContentResolver.update(voicemailUri, values, null, null);
         if (updatedCount != 1) {
             throw new IOException("Updating voicemail should have updated 1 row, was: "
                     + updatedCount);
         }
-        logger.d(String.format("Writing new voicemail content: %s", voicemailUri));
-        return mContentResolver.openOutputStream(voicemailUri);
     }
 
     @Override
@@ -288,4 +318,13 @@
         }
         return contentValues;
     }
+
+    private void copyStreamData(InputStream in, OutputStream out) throws IOException {
+        byte[] data = new byte[8 * 1024];
+        int numBytes;
+        while ((numBytes = in.read(data)) > 0) {
+            out.write(data, 0, numBytes);
+        }
+
+    }
 }
diff --git a/samples/WeatherListWidget/AndroidManifest.xml b/samples/WeatherListWidget/AndroidManifest.xml
index cfb2372..7b1638f 100644
--- a/samples/WeatherListWidget/AndroidManifest.xml
+++ b/samples/WeatherListWidget/AndroidManifest.xml
@@ -21,7 +21,9 @@
      to come from a domain that you own or have control over. -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.weatherlistwidget">
-    <uses-sdk android:minSdkVersion="11" />
+
+    <uses-sdk android:minSdkVersion="11"
+              android:targetSdkVersion="14"/>
     <application android:label="Weather Widget Sample">
         <!-- The widget provider -->
         <receiver android:name="WeatherWidgetProvider">
@@ -42,4 +44,4 @@
         <provider android:name="WeatherDataProvider"
               android:authorities="com.example.android.weatherlistwidget.provider" />
     </application>
-</manifest>
\ No newline at end of file
+</manifest>
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/body.png b/samples/WeatherListWidget/res/drawable-hdpi/body.png
index 0a2c1d1..17d303f 100644
--- a/samples/WeatherListWidget/res/drawable-hdpi/body.png
+++ b/samples/WeatherListWidget/res/drawable-hdpi/body.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/footer.png b/samples/WeatherListWidget/res/drawable-hdpi/footer.png
index 73cc95c..43962f7 100644
--- a/samples/WeatherListWidget/res/drawable-hdpi/footer.png
+++ b/samples/WeatherListWidget/res/drawable-hdpi/footer.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/header.9.png b/samples/WeatherListWidget/res/drawable-hdpi/header.9.png
new file mode 100644
index 0000000..5f34768
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-hdpi/header.9.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/header.png b/samples/WeatherListWidget/res/drawable-hdpi/header.png
deleted file mode 100644
index e659aee..0000000
--- a/samples/WeatherListWidget/res/drawable-hdpi/header.png
+++ /dev/null
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/item_bg_dark.png b/samples/WeatherListWidget/res/drawable-hdpi/item_bg_dark.png
index 5097ab7..f5886bd 100644
--- a/samples/WeatherListWidget/res/drawable-hdpi/item_bg_dark.png
+++ b/samples/WeatherListWidget/res/drawable-hdpi/item_bg_dark.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/item_bg_light.png b/samples/WeatherListWidget/res/drawable-hdpi/item_bg_light.png
index 019f36c..e8b5aaf 100644
--- a/samples/WeatherListWidget/res/drawable-hdpi/item_bg_light.png
+++ b/samples/WeatherListWidget/res/drawable-hdpi/item_bg_light.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/refresh.png b/samples/WeatherListWidget/res/drawable-hdpi/refresh.png
index 2847773..eaec9cb 100644
--- a/samples/WeatherListWidget/res/drawable-hdpi/refresh.png
+++ b/samples/WeatherListWidget/res/drawable-hdpi/refresh.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-hdpi/refresh_pressed.png b/samples/WeatherListWidget/res/drawable-hdpi/refresh_pressed.png
index 820cc36..34438b7 100644
--- a/samples/WeatherListWidget/res/drawable-hdpi/refresh_pressed.png
+++ b/samples/WeatherListWidget/res/drawable-hdpi/refresh_pressed.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/body.png b/samples/WeatherListWidget/res/drawable-ldpi/body.png
deleted file mode 100644
index 3ce4276..0000000
--- a/samples/WeatherListWidget/res/drawable-ldpi/body.png
+++ /dev/null
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/footer.png b/samples/WeatherListWidget/res/drawable-ldpi/footer.png
deleted file mode 100644
index ab89bf3..0000000
--- a/samples/WeatherListWidget/res/drawable-ldpi/footer.png
+++ /dev/null
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/header.png b/samples/WeatherListWidget/res/drawable-ldpi/header.png
deleted file mode 100644
index ff29577..0000000
--- a/samples/WeatherListWidget/res/drawable-ldpi/header.png
+++ /dev/null
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/item_bg_dark.png b/samples/WeatherListWidget/res/drawable-ldpi/item_bg_dark.png
deleted file mode 100644
index c945b5f..0000000
--- a/samples/WeatherListWidget/res/drawable-ldpi/item_bg_dark.png
+++ /dev/null
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/item_bg_light.png b/samples/WeatherListWidget/res/drawable-ldpi/item_bg_light.png
deleted file mode 100644
index a14b9a6..0000000
--- a/samples/WeatherListWidget/res/drawable-ldpi/item_bg_light.png
+++ /dev/null
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/refresh.png b/samples/WeatherListWidget/res/drawable-ldpi/refresh.png
deleted file mode 100644
index d08343c..0000000
--- a/samples/WeatherListWidget/res/drawable-ldpi/refresh.png
+++ /dev/null
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/refresh_pressed.png b/samples/WeatherListWidget/res/drawable-ldpi/refresh_pressed.png
deleted file mode 100644
index 3da3ae6..0000000
--- a/samples/WeatherListWidget/res/drawable-ldpi/refresh_pressed.png
+++ /dev/null
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/body.png b/samples/WeatherListWidget/res/drawable-mdpi/body.png
index 5331a9a..a08d03b 100644
--- a/samples/WeatherListWidget/res/drawable-mdpi/body.png
+++ b/samples/WeatherListWidget/res/drawable-mdpi/body.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/footer.png b/samples/WeatherListWidget/res/drawable-mdpi/footer.png
index ca8b7ec..d3960a7 100644
--- a/samples/WeatherListWidget/res/drawable-mdpi/footer.png
+++ b/samples/WeatherListWidget/res/drawable-mdpi/footer.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/header.9.png b/samples/WeatherListWidget/res/drawable-mdpi/header.9.png
new file mode 100644
index 0000000..2372225
--- /dev/null
+++ b/samples/WeatherListWidget/res/drawable-mdpi/header.9.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/header.png b/samples/WeatherListWidget/res/drawable-mdpi/header.png
deleted file mode 100644
index 5452abf..0000000
--- a/samples/WeatherListWidget/res/drawable-mdpi/header.png
+++ /dev/null
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/item_bg_dark.png b/samples/WeatherListWidget/res/drawable-mdpi/item_bg_dark.png
index 5ae5480..a3ac9d7 100644
--- a/samples/WeatherListWidget/res/drawable-mdpi/item_bg_dark.png
+++ b/samples/WeatherListWidget/res/drawable-mdpi/item_bg_dark.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/item_bg_light.png b/samples/WeatherListWidget/res/drawable-mdpi/item_bg_light.png
index 5696944..ec6f5aa 100644
--- a/samples/WeatherListWidget/res/drawable-mdpi/item_bg_light.png
+++ b/samples/WeatherListWidget/res/drawable-mdpi/item_bg_light.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/refresh.png b/samples/WeatherListWidget/res/drawable-mdpi/refresh.png
index 569b360..006bcc5 100644
--- a/samples/WeatherListWidget/res/drawable-mdpi/refresh.png
+++ b/samples/WeatherListWidget/res/drawable-mdpi/refresh.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-mdpi/refresh_pressed.png b/samples/WeatherListWidget/res/drawable-mdpi/refresh_pressed.png
index 5f10662..d8ca9b5 100644
--- a/samples/WeatherListWidget/res/drawable-mdpi/refresh_pressed.png
+++ b/samples/WeatherListWidget/res/drawable-mdpi/refresh_pressed.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/layout/widget_layout.xml b/samples/WeatherListWidget/res/layout/widget_layout.xml
index 4b09efc..4c58fa7 100644
--- a/samples/WeatherListWidget/res/layout/widget_layout.xml
+++ b/samples/WeatherListWidget/res/layout/widget_layout.xml
@@ -14,9 +14,15 @@
      limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="294dp"
+    android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:orientation="vertical">
+    android:orientation="vertical"
+    android:layout_marginTop="@dimen/widget_margin_top"
+    android:layout_marginBottom="@dimen/widget_margin_bottom"
+    android:layout_marginLeft="@dimen/widget_margin_left"
+    android:layout_marginRight="@dimen/widget_margin_right">
+    <!-- We define separate margins to allow for flexibility in twiddling the margins
+         depending on device form factor and target SDK version. -->
     <FrameLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content">
@@ -24,12 +30,14 @@
             android:id="@+id/header"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
+            android:scaleType="fitXY"
             android:src="@drawable/header" />
         <ImageButton
             android:id="@+id/refresh"
             android:layout_width="56dp"
             android:layout_height="39dp"
-            android:layout_marginLeft="222dp"
+            android:layout_gravity="right|top"
+            android:layout_marginRight="15dp"
             android:layout_marginTop="20dp"
             android:background="@drawable/refresh_button" />
     </FrameLayout>
@@ -57,5 +65,6 @@
         android:id="@+id/footer"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:scaleType="fitXY"
         android:src="@drawable/footer" />
 </LinearLayout>
diff --git a/samples/SampleSyncAdapter/res/values/styles.xml b/samples/WeatherListWidget/res/values-v14/dimens.xml
similarity index 64%
copy from samples/SampleSyncAdapter/res/values/styles.xml
copy to samples/WeatherListWidget/res/values-v14/dimens.xml
index 074613e..8b5494e 100644
--- a/samples/SampleSyncAdapter/res/values/styles.xml
+++ b/samples/WeatherListWidget/res/values-v14/dimens.xml
@@ -13,15 +13,9 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <resources>
-    <!--
-        These styles will only be used in Honeycomb and later because
-        Android doesn't support third-party contact editing in pre-
-        Honeycomb versions.
-    -->
-    <color name="EditPanelBackgroundColor">#ffffff</color>
-    <color name="EditPanelBorderColor">#cccccc</color>
-    <style name="ContactEditTheme" parent="android:Theme.Holo.Light">
-    </style>
+    <dimen name="widget_margin_top">0dp</dimen>
+    <dimen name="widget_margin_bottom">0dp</dimen>
+    <dimen name="widget_margin_left">0dp</dimen>
+    <dimen name="widget_margin_right">0dp</dimen>
 </resources>
diff --git a/samples/SampleSyncAdapter/res/values/styles.xml b/samples/WeatherListWidget/res/values/dimens.xml
similarity index 64%
copy from samples/SampleSyncAdapter/res/values/styles.xml
copy to samples/WeatherListWidget/res/values/dimens.xml
index 074613e..00257a9 100644
--- a/samples/SampleSyncAdapter/res/values/styles.xml
+++ b/samples/WeatherListWidget/res/values/dimens.xml
@@ -13,15 +13,9 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-
 <resources>
-    <!--
-        These styles will only be used in Honeycomb and later because
-        Android doesn't support third-party contact editing in pre-
-        Honeycomb versions.
-    -->
-    <color name="EditPanelBackgroundColor">#ffffff</color>
-    <color name="EditPanelBorderColor">#cccccc</color>
-    <style name="ContactEditTheme" parent="android:Theme.Holo.Light">
-    </style>
-</resources>
+    <dimen name="widget_margin_top">8dp</dimen>
+    <dimen name="widget_margin_bottom">8dp</dimen>
+    <dimen name="widget_margin_left">8dp</dimen>
+    <dimen name="widget_margin_right">8dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/samples/WeatherListWidget/res/xml/widgetinfo.xml b/samples/WeatherListWidget/res/xml/widgetinfo.xml
index af64106..e6e9cf3 100644
--- a/samples/WeatherListWidget/res/xml/widgetinfo.xml
+++ b/samples/WeatherListWidget/res/xml/widgetinfo.xml
@@ -15,10 +15,12 @@
 -->
 <appwidget-provider
   xmlns:android="http://schemas.android.com/apk/res/android"
-  android:minWidth="222dip"
-  android:minHeight="222dip"
+  android:minWidth="250dp"
+  android:minHeight="180dp"
   android:updatePeriodMillis="1800000"
   android:initialLayout="@layout/widget_layout"
   android:resizeMode="vertical"
+  android:minResizeWidth="250dp"
+  android:minResizeHeight="110dp"
   android:previewImage="@drawable/preview">
 </appwidget-provider>
diff --git a/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.java b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.java
index e0bc682..1d3c349 100644
--- a/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.java
+++ b/samples/WeatherListWidget/src/com/example/android/weatherlistwidget/WeatherWidgetService.java
@@ -123,4 +123,4 @@
         mCursor = mContext.getContentResolver().query(WeatherDataProvider.CONTENT_URI, null, null,
                 null, null);
     }
-}
\ No newline at end of file
+}
diff --git a/samples/WiFiDirectDemo/Android.mk b/samples/WiFiDirectDemo/Android.mk
new file mode 100644
index 0000000..f77bb85
--- /dev/null
+++ b/samples/WiFiDirectDemo/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := WiFiDirectDemo
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/WiFiDirectDemo/AndroidManifest.xml b/samples/WiFiDirectDemo/AndroidManifest.xml
new file mode 100644
index 0000000..993716f
--- /dev/null
+++ b/samples/WiFiDirectDemo/AndroidManifest.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.wifidirect"
+    android:versionCode="1" android:versionName="1.0">
+
+    <uses-sdk android:minSdkVersion="14" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+    <!-- Market filtering --> 
+    <uses-feature android:name="android.hardware.wifi.direct" android:required="true"/>
+
+    <application
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@android:style/Theme.Holo">
+        <activity
+            android:name=".WiFiDirectActivity"
+            android:label="@string/app_name" android:launchMode="singleTask">
+            <intent-filter>
+                <action
+                    android:name="android.intent.action.MAIN" />
+                <category
+                    android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <!-- Used for transferring files  after a successful connection -->
+        <service android:enabled="true" android:name=".FileTransferService" />
+
+    </application>
+</manifest>
diff --git a/samples/WiFiDirectDemo/_index.html b/samples/WiFiDirectDemo/_index.html
new file mode 100644
index 0000000..07fb190
--- /dev/null
+++ b/samples/WiFiDirectDemo/_index.html
@@ -0,0 +1,49 @@
+<p>This is a demo application highlighting how to make peer to peer network connections with
+the Wi-Fi Direct APIs.  The application allows you to transfer jpeg images from the gallery after a succesful connection.</p>
+
+<p>The source code for this demo app shows how to accomplish three key things
+with Wi-Fi Direct APIs: Discovering peers, connecting using Wi-Fi Direct APIs, and finding group details post connection, so that a 
+TCP socket can be opened to transfer files.</p>
+
+<p>The application includes:<p>
+<ul> <li><a
+    href="src/com/example/android/wifidirect/WiFiDirectActivity.html"><code>WiFiDirectActivity</code></a>
+  &mdash; the main <code>Activity</code> that contains two fragments to handle app's UI and peer lifecycle. It also registers a broadcast receiver for Wi-Fi Direct related events.</li> <li><a
+    href="src/com/example/android/wifidirect/WiFiDirectBroadcastReceiver.html"><code>
+      WiFiDirectBroadcastReceiver</code></a> &mdash; a <code>BroadcastReceiver</code>
+  that listens for Wi-Fi Direct related events and passes them to
+  <code>WiFiDirectActivity</code> and it's fragments for neccesary action.</li> <li><a
+    href="src/com/example/android/wifidirect/DeviceListFragment.html"><code>DeviceListFragment</code></a>
+  &mdash; a <code>ListFragment</code> that displays available peers and their status. </li>
+<li><a href="src/com/example/android/wifidirect/DeviceDetailFragment.html"><code>DeviceDetailFragment</code></a>
+  &mdash; a <code>Fragment</code> that displays the details of the selected device and also drives the connection, disonnection and data transfer functionality of the demo. </li>
+<li><a href="src/com/example/android/wifidirect/FileTransferService.html"><code>FileTransferService</code></a>
+  &mdash; an <code>IntentService</code> that services file transfer requests from the application by using TCP sockets. </li> </ul>
+<p>If you are developing an application that uses the Wi-Fi Direct APIs, remember that the
+feature is supported only on Android 4.0 (API level 14) and higher versions of
+the platform. To ensure that your application can only
+be installed on devices that are capable of supporting Wi-Fi Direct mode, remember to add the
+following to the application's manifest before publishing to Android Market:</p>
+<ul> <li><code>&lt;uses-sdk android:minSdkVersion="14" /&gt;</code>, which
+  indicates to Android Market and the platform that your application requires
+  Android 4.0 or higher. For more information, see <a
+    href="../../../guide/appendix/api-levels.html">API Levels</a> and the
+  documentation for the <a
+    href="../../../guide/topics/manifest/uses-sdk-element.html"><code>&lt;uses-sdk&gt;</code></a>
+  element.</li> </ul> <p>To control how Android Market filters your application
+from devices that do not support Wi-Fi Direct mode, remember to add the following to the
+application's manifest <ul> <li><code>&lt;uses-feature
+    android:name="android.hardware.wifi.direct" /&gt;</code>, which tells Android
+  Market that your application uses the Wi-Fi Direct API. The declaration should include
+  an <code>android:required</code> attribute that indicates whether you want
+  Android Market to filter the application from devices that do not offer Wi-Fi Direct support. Other <code>&lt;uses-feature&gt;</code> declarations may also be
+  needed, depending on your implementation. For more information, see the
+  documentation for the <a
+    href="../../../guide/topics/manifest/uses-feature-element.html"><code>&lt;uses-feature&gt;</code></a>
+  element.</li> </ul>
+<p>For more information about using the Wi-Fi Direct API, see the <a
+  href="../../../reference/android/net/wifi/p2p/package-summary.html"><code>android.net.wifi.p2p	</a></code>
+documentation. </p>
+
+<img alt="" src="../images/WifiDirect.png" />
+
diff --git a/samples/WiFiDirectDemo/assets/sample_file.txt b/samples/WiFiDirectDemo/assets/sample_file.txt
new file mode 100644
index 0000000..504dbf5
--- /dev/null
+++ b/samples/WiFiDirectDemo/assets/sample_file.txt
@@ -0,0 +1,3 @@
+This is a sample text file for wifi_direct demo. 
+
+Once the devices are connected, the server i.e. groupOwner will listen for incoming connections and write this file. 
\ No newline at end of file
diff --git a/samples/WiFiDirectDemo/res/drawable-hdpi/ic_action_discover.png b/samples/WiFiDirectDemo/res/drawable-hdpi/ic_action_discover.png
new file mode 100644
index 0000000..98241d7
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-hdpi/ic_action_discover.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-hdpi/ic_action_on_off.png b/samples/WiFiDirectDemo/res/drawable-hdpi/ic_action_on_off.png
new file mode 100644
index 0000000..5eabf08
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-hdpi/ic_action_on_off.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-hdpi/ic_launcher.png b/samples/WiFiDirectDemo/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..f2a2f25
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-hdpi/icon.png b/samples/WiFiDirectDemo/res/drawable-hdpi/icon.png
new file mode 100644
index 0000000..8074c4c
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-ldpi/ic_action_discover.png b/samples/WiFiDirectDemo/res/drawable-ldpi/ic_action_discover.png
new file mode 100644
index 0000000..12849ed
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-ldpi/ic_action_discover.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-ldpi/ic_action_on_off.png b/samples/WiFiDirectDemo/res/drawable-ldpi/ic_action_on_off.png
new file mode 100644
index 0000000..e84700a
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-ldpi/ic_action_on_off.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-ldpi/ic_launcher.png b/samples/WiFiDirectDemo/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000..002dae2
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/samples/WeatherListWidget/res/drawable-ldpi/icon.png b/samples/WiFiDirectDemo/res/drawable-ldpi/icon.png
similarity index 100%
copy from samples/WeatherListWidget/res/drawable-ldpi/icon.png
copy to samples/WiFiDirectDemo/res/drawable-ldpi/icon.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-mdpi/ic_action_discover.png b/samples/WiFiDirectDemo/res/drawable-mdpi/ic_action_discover.png
new file mode 100644
index 0000000..bd71a10
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-mdpi/ic_action_discover.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-mdpi/ic_action_on_off.png b/samples/WiFiDirectDemo/res/drawable-mdpi/ic_action_on_off.png
new file mode 100644
index 0000000..8e49066
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-mdpi/ic_action_on_off.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-mdpi/ic_launcher.png b/samples/WiFiDirectDemo/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..c3792d0
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-mdpi/icon.png b/samples/WiFiDirectDemo/res/drawable-mdpi/icon.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-xhdpi/ic_action_discover.png b/samples/WiFiDirectDemo/res/drawable-xhdpi/ic_action_discover.png
new file mode 100644
index 0000000..543e2a0
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-xhdpi/ic_action_discover.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-xhdpi/ic_action_on_off.png b/samples/WiFiDirectDemo/res/drawable-xhdpi/ic_action_on_off.png
new file mode 100644
index 0000000..3d30ac9
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-xhdpi/ic_action_on_off.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable-xhdpi/ic_launcher.png b/samples/WiFiDirectDemo/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..c6d8a02
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable/details_view.xml b/samples/WiFiDirectDemo/res/drawable/details_view.xml
new file mode 100644
index 0000000..06fb95a
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable/details_view.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    
+    <solid android:color="@color/layout_border_color"/>
+    <stroke
+        android:width="4dp"
+        android:color="@android:color/background_dark" />
+    <padding
+        android:left="10dp"
+        android:top="2dp"
+        android:right="10dp"
+        android:bottom="2dp" />
+</shape>
diff --git a/samples/WiFiDirectDemo/res/drawable/machine.png b/samples/WiFiDirectDemo/res/drawable/machine.png
new file mode 100644
index 0000000..d61609a
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable/machine.png
Binary files differ
diff --git a/samples/WiFiDirectDemo/res/drawable/section_header.xml b/samples/WiFiDirectDemo/res/drawable/section_header.xml
new file mode 100644
index 0000000..22344dc
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/drawable/section_header.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <stroke
+        android:width="2dp"
+        android:color="@color/layout_border_color" />
+
+    <padding
+        android:left="10dp"
+        android:top="5dp"
+        android:right="10dp"
+        android:bottom="2dp" />
+    <corners
+        android:radius="2dp" />
+</shape>
diff --git a/samples/WiFiDirectDemo/res/layout-land/main.xml b/samples/WiFiDirectDemo/res/layout-land/main.xml
new file mode 100644
index 0000000..55b0d09
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/layout-land/main.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:id="@+id/linearLayout1"
+        android:layout_height="match_parent"
+        android:orientation="horizontal">
+        <fragment
+            class="com.example.android.wifidirect.DeviceListFragment"
+            android:id="@+id/frag_list"
+            android:layout_width="@dimen/phone_list_height"
+            android:layout_height="match_parent">
+            <!-- Preview: layout=@layout/row_devices -->
+        </fragment>
+        <fragment
+            class="com.example.android.wifidirect.DeviceDetailFragment"
+            android:id="@+id/frag_detail"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+            <!-- Preview: layout=@layout/device_detail -->
+        </fragment>
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/WiFiDirectDemo/res/layout-large/main.xml b/samples/WiFiDirectDemo/res/layout-large/main.xml
new file mode 100644
index 0000000..b278d64
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/layout-large/main.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical" android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    <LinearLayout android:layout_width="match_parent" android:id="@+id/linearLayout1"
+        android:layout_height="fill_parent" android:orientation="horizontal">
+        <fragment class="com.example.android.wifidirect.DeviceListFragment"
+            android:id="@+id/frag_list" android:layout_width="@dimen/tablet_list_width"
+            android:layout_height="match_parent">
+            <!-- Preview: layout=@layout/row_devices -->
+        </fragment>
+        <fragment class="com.example.android.wifidirect.DeviceDetailFragment"
+            android:id="@+id/frag_detail" android:layout_width="match_parent"
+            android:layout_height="match_parent">
+            <!-- Preview: layout=@layout/device_detail -->
+        </fragment>
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/WiFiDirectDemo/res/layout/device_detail.xml b/samples/WiFiDirectDemo/res/layout/device_detail.xml
new file mode 100644
index 0000000..40509b1
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/layout/device_detail.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="horizontal"
+    android:layout_width="match_parent"
+    android:layout_height="fill_parent"
+    android:background="@drawable/details_view"
+    android:visibility="gone">
+    <LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:orientation="vertical"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <LinearLayout
+            xmlns:android="http://schemas.android.com/apk/res/android"
+            android:orientation="horizontal"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+            <Button
+                android:id="@+id/btn_connect"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/connect_peer_button" />
+            <Button
+                android:id="@+id/btn_disconnect"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/disconnect_peer_button" />
+            <Button
+                android:id="@+id/btn_start_client"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="@string/get_file_button"
+                android:visibility="gone" />
+        </LinearLayout>
+        <TextView
+            android:id="@+id/device_address"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+        <TextView
+            android:id="@+id/device_info"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+        <TextView
+            android:id="@+id/group_owner"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+        <TextView
+            android:id="@+id/group_ip"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content" />
+    </LinearLayout>
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:id="@+id/status_bar"
+        android:orientation="vertical"
+        android:layout_gravity="bottom"
+        android:layout_height="37dp"
+        android:layout_marginBottom="3dp"
+        android:background="@android:color/background_dark">
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_gravity="center"
+            android:layout_margin="5dp"
+            android:textColor="@android:color/white"
+            android:id="@+id/status_text">
+        </TextView>
+    </LinearLayout>
+</FrameLayout>
diff --git a/samples/WiFiDirectDemo/res/layout/device_list.xml b/samples/WiFiDirectDemo/res/layout/device_list.xml
new file mode 100644
index 0000000..2d91566
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/layout/device_list.xml
@@ -0,0 +1,80 @@
+<?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"
+    android:paddingTop="3dp">
+
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:text="@string/label_me" />
+    <View
+        android:layout_width="fill_parent"
+        android:layout_height="1dp"
+        android:gravity="center_vertical"
+        android:background="@android:color/holo_blue_light" />
+
+    <!-- Self information -->
+    <LinearLayout
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="fill_parent"
+        android:layout_height="?android:attr/listPreferredItemHeight"
+        android:background="?android:attr/activatedBackgroundIndicator"
+        android:padding="3dip">
+        <ImageView
+            android:id="@+id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="fill_parent"
+            android:layout_marginRight="2dp"
+            android:src="@drawable/machine" />
+        <LinearLayout
+            android:orientation="vertical"
+            android:layout_width="0dp"
+            android:layout_weight="1"
+            android:layout_height="fill_parent">
+            <TextView
+                android:id="@+id/my_name"
+                android:layout_width="fill_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:gravity="center_vertical" />
+            <TextView
+                android:id="@+id/my_status"
+                android:layout_width="fill_parent"
+                android:layout_height="0dp"
+                android:layout_weight="1"
+                android:singleLine="true"
+                android:ellipsize="marquee" />
+        </LinearLayout>
+    </LinearLayout>
+
+    <TextView
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center_vertical"
+        android:text="@string/label_peers" />
+
+    <View
+        android:layout_width="fill_parent"
+        android:layout_height="1dp"
+        android:gravity="center_vertical"
+        android:background="@android:color/holo_blue_light" />
+
+    <!-- Available peers -->
+    <ListView
+        android:id="@id/android:list"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_weight="1"
+        android:drawSelectorOnTop="false" />
+
+    <TextView
+        android:id="@id/android:empty"
+        android:layout_width="match_parent"
+        android:layout_gravity="center"
+        android:layout_height="match_parent"
+        android:text="@string/empty_message" />
+</LinearLayout>
diff --git a/samples/WiFiDirectDemo/res/layout/main.xml b/samples/WiFiDirectDemo/res/layout/main.xml
new file mode 100644
index 0000000..70151d5
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/layout/main.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent">
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:id="@+id/linearLayout1"
+        android:layout_height="match_parent"
+        android:orientation="vertical">
+        <fragment
+            class="com.example.android.wifidirect.DeviceListFragment"
+            android:id="@+id/frag_list"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/phone_list_height">
+            <!-- Preview: layout=@layout/row_devices -->
+        </fragment>
+        <fragment
+            class="com.example.android.wifidirect.DeviceDetailFragment"
+            android:id="@+id/frag_detail"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent">
+            <!-- Preview: layout=@layout/device_detail -->
+        </fragment>
+    </LinearLayout>
+</LinearLayout>
diff --git a/samples/WiFiDirectDemo/res/layout/row_devices.xml b/samples/WiFiDirectDemo/res/layout/row_devices.xml
new file mode 100644
index 0000000..f5b68fa
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/layout/row_devices.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="fill_parent"
+    android:layout_height="?android:attr/listPreferredItemHeight"
+    android:background="?android:attr/activatedBackgroundIndicator"
+    android:padding="6dip">
+    <ImageView
+        android:id="@+id/icon"
+        android:layout_width="wrap_content"
+        android:layout_height="fill_parent"
+        android:layout_marginRight="2dip"
+        android:src="@drawable/machine" />
+    <LinearLayout
+        android:orientation="vertical"
+        android:layout_width="0dip"
+        android:layout_weight="1"
+        android:layout_height="fill_parent">
+        <TextView
+            android:id="@+id/device_name"
+            android:layout_width="fill_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1"
+            android:gravity="center_vertical" />
+        <TextView
+            android:layout_width="fill_parent"
+            android:layout_height="0dip"
+            android:layout_weight="1"
+            android:id="@+id/device_details"
+            android:singleLine="true"
+            android:ellipsize="marquee" />
+    </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/samples/WiFiDirectDemo/res/menu/action_items.xml b/samples/WiFiDirectDemo/res/menu/action_items.xml
new file mode 100644
index 0000000..d2d3c7c
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/menu/action_items.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:id="@+id/atn_direct_enable"
+        android:icon="@drawable/ic_action_on_off"
+        android:title="@string/enable_p2p_button"
+        android:showAsAction="ifRoom|withText" />
+
+    <item
+        android:id="@+id/atn_direct_discover"
+        android:icon="@drawable/ic_action_discover"
+        android:title="@string/discover_peers_button"
+        android:showAsAction="ifRoom|withText" />
+</menu>
diff --git a/samples/WiFiDirectDemo/res/values/colors.xml b/samples/WiFiDirectDemo/res/values/colors.xml
new file mode 100644
index 0000000..6dae474
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/values/colors.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <color name="status_bar_color">#FF000000</color>
+    <color name="layout_border_color">#FF111111</color>
+</resources>
diff --git a/samples/WiFiDirectDemo/res/values/dimens.xml b/samples/WiFiDirectDemo/res/values/dimens.xml
new file mode 100644
index 0000000..9ff9f12
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/values/dimens.xml
@@ -0,0 +1,21 @@
+<?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>
+    <dimen name="tablet_list_width">300dp</dimen>
+    <dimen name="phone_list_height">200dp</dimen>
+    
+</resources>
\ No newline at end of file
diff --git a/samples/WiFiDirectDemo/res/values/strings.xml b/samples/WiFiDirectDemo/res/values/strings.xml
new file mode 100644
index 0000000..96042b6
--- /dev/null
+++ b/samples/WiFiDirectDemo/res/values/strings.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">WiFi Direct</string>
+    <string name="enable_p2p_button">P2P On/Off</string>
+    <string name="discover_peers_button">Discover</string>
+    <string name="connect_peer_button">Connect</string>
+    <string name="disconnect_peer_button">Disconnect</string>
+    <string name="get_file_button">Launch Gallery</string>
+    <string name="empty"></string>
+    <string name="yes">yes</string>
+    <string name="no">no</string>
+    <string name="client_text">This device will act as a client. Click on Gallery button to pick a local(stored) file</string>
+    <string name="empty_message">No devices found. Turn on P2P and perform discovery from the Action Bar</string>
+    <string name="p2p_off_warning">Enable P2P from action bar button above or system settings</string>
+    <string name="group_owner_text">"Am I the Group Owner? "</string>
+    <string name="label_me">ME</string>
+    <string name="label_peers">PEERS</string>
+</resources>
diff --git a/samples/WiFiDirectDemo/src/com/example/android/wifidirect/DeviceDetailFragment.java b/samples/WiFiDirectDemo/src/com/example/android/wifidirect/DeviceDetailFragment.java
new file mode 100644
index 0000000..f74afae
--- /dev/null
+++ b/samples/WiFiDirectDemo/src/com/example/android/wifidirect/DeviceDetailFragment.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.wifidirect;
+
+import android.app.Fragment;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.net.Uri;
+import android.net.wifi.WpsInfo;
+import android.net.wifi.p2p.WifiP2pConfig;
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pInfo;
+import android.net.wifi.p2p.WifiP2pManager.ConnectionInfoListener;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.example.android.wifidirect.DeviceListFragment.DeviceActionListener;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+/**
+ * A fragment that manages a particular peer and allows interaction with device
+ * i.e. setting up network connection and transferring data.
+ */
+public class DeviceDetailFragment extends Fragment implements ConnectionInfoListener {
+
+    protected static final int CHOOSE_FILE_RESULT_CODE = 20;
+    private View mContentView = null;
+    private WifiP2pDevice device;
+    private WifiP2pInfo info;
+    ProgressDialog progressDialog = null;
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+
+        mContentView = inflater.inflate(R.layout.device_detail, null);
+        mContentView.findViewById(R.id.btn_connect).setOnClickListener(new View.OnClickListener() {
+
+            @Override
+            public void onClick(View v) {
+                WifiP2pConfig config = new WifiP2pConfig();
+                config.deviceAddress = device.deviceAddress;
+                config.wps.setup = WpsInfo.PBC;
+                if (progressDialog != null && progressDialog.isShowing()) {
+                    progressDialog.dismiss();
+                }
+                progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel",
+                        "Connecting to :" + device.deviceAddress, true, true
+//                        new DialogInterface.OnCancelListener() {
+//
+//                            @Override
+//                            public void onCancel(DialogInterface dialog) {
+//                                ((DeviceActionListener) getActivity()).cancelDisconnect();
+//                            }
+//                        }
+                        );
+                ((DeviceActionListener) getActivity()).connect(config);
+
+            }
+        });
+
+        mContentView.findViewById(R.id.btn_disconnect).setOnClickListener(
+                new View.OnClickListener() {
+
+                    @Override
+                    public void onClick(View v) {
+                        ((DeviceActionListener) getActivity()).disconnect();
+                    }
+                });
+
+        mContentView.findViewById(R.id.btn_start_client).setOnClickListener(
+                new View.OnClickListener() {
+
+                    @Override
+                    public void onClick(View v) {
+                        // Allow user to pick an image from Gallery or other
+                        // registered apps
+                        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+                        intent.setType("image/*");
+                        startActivityForResult(intent, CHOOSE_FILE_RESULT_CODE);
+                    }
+                });
+
+        return mContentView;
+    }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+
+        // User has picked an image. Transfer it to group owner i.e peer using
+        // FileTransferService.
+        Uri uri = data.getData();
+        TextView statusText = (TextView) mContentView.findViewById(R.id.status_text);
+        statusText.setText("Sending: " + uri);
+        Log.d(WiFiDirectActivity.TAG, "Intent----------- " + uri);
+        Intent serviceIntent = new Intent(getActivity(), FileTransferService.class);
+        serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
+        serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
+        serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS,
+                info.groupOwnerAddress.getHostAddress());
+        serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988);
+        getActivity().startService(serviceIntent);
+    }
+
+    @Override
+    public void onConnectionInfoAvailable(final WifiP2pInfo info) {
+        if (progressDialog != null && progressDialog.isShowing()) {
+            progressDialog.dismiss();
+        }
+        this.info = info;
+        this.getView().setVisibility(View.VISIBLE);
+
+        // The owner IP is now known.
+        TextView view = (TextView) mContentView.findViewById(R.id.group_owner);
+        view.setText(getResources().getString(R.string.group_owner_text)
+                + ((info.isGroupOwner == true) ? getResources().getString(R.string.yes)
+                        : getResources().getString(R.string.no)));
+
+        // InetAddress from WifiP2pInfo struct.
+        view = (TextView) mContentView.findViewById(R.id.device_info);
+        view.setText("Group Owner IP - " + info.groupOwnerAddress.getHostAddress());
+
+        // After the group negotiation, we assign the group owner as the file
+        // server. The file server is single threaded, single connection server
+        // socket.
+        if (info.groupFormed && info.isGroupOwner) {
+            new FileServerAsyncTask(getActivity(), mContentView.findViewById(R.id.status_text))
+                    .execute();
+        } else if (info.groupFormed) {
+            // The other device acts as the client. In this case, we enable the
+            // get file button.
+            mContentView.findViewById(R.id.btn_start_client).setVisibility(View.VISIBLE);
+            ((TextView) mContentView.findViewById(R.id.status_text)).setText(getResources()
+                    .getString(R.string.client_text));
+        }
+
+        // hide the connect button
+        mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
+    }
+
+    /**
+     * Updates the UI with device data
+     * 
+     * @param device the device to be displayed
+     */
+    public void showDetails(WifiP2pDevice device) {
+        this.device = device;
+        this.getView().setVisibility(View.VISIBLE);
+        TextView view = (TextView) mContentView.findViewById(R.id.device_address);
+        view.setText(device.deviceAddress);
+        view = (TextView) mContentView.findViewById(R.id.device_info);
+        view.setText(device.toString());
+
+    }
+
+    /**
+     * Clears the UI fields after a disconnect or direct mode disable operation.
+     */
+    public void resetViews() {
+        mContentView.findViewById(R.id.btn_connect).setVisibility(View.VISIBLE);
+        TextView view = (TextView) mContentView.findViewById(R.id.device_address);
+        view.setText(R.string.empty);
+        view = (TextView) mContentView.findViewById(R.id.device_info);
+        view.setText(R.string.empty);
+        view = (TextView) mContentView.findViewById(R.id.group_owner);
+        view.setText(R.string.empty);
+        view = (TextView) mContentView.findViewById(R.id.status_text);
+        view.setText(R.string.empty);
+        mContentView.findViewById(R.id.btn_start_client).setVisibility(View.GONE);
+        this.getView().setVisibility(View.GONE);
+    }
+
+    /**
+     * A simple server socket that accepts connection and writes some data on
+     * the stream.
+     */
+    public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
+
+        private Context context;
+        private TextView statusText;
+
+        /**
+         * @param context
+         * @param statusText
+         */
+        public FileServerAsyncTask(Context context, View statusText) {
+            this.context = context;
+            this.statusText = (TextView) statusText;
+        }
+
+        @Override
+        protected String doInBackground(Void... params) {
+            try {
+                ServerSocket serverSocket = new ServerSocket(8988);
+                Log.d(WiFiDirectActivity.TAG, "Server: Socket opened");
+                Socket client = serverSocket.accept();
+                Log.d(WiFiDirectActivity.TAG, "Server: connection done");
+                final File f = new File(Environment.getExternalStorageDirectory() + "/"
+                        + context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
+                        + ".jpg");
+
+                File dirs = new File(f.getParent());
+                if (!dirs.exists())
+                    dirs.mkdirs();
+                f.createNewFile();
+
+                Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
+                InputStream inputstream = client.getInputStream();
+                copyFile(inputstream, new FileOutputStream(f));
+                serverSocket.close();
+                return f.getAbsolutePath();
+            } catch (IOException e) {
+                Log.e(WiFiDirectActivity.TAG, e.getMessage());
+                return null;
+            }
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
+         */
+        @Override
+        protected void onPostExecute(String result) {
+            if (result != null) {
+                statusText.setText("File copied - " + result);
+                Intent intent = new Intent();
+                intent.setAction(android.content.Intent.ACTION_VIEW);
+                intent.setDataAndType(Uri.parse("file://" + result), "image/*");
+                context.startActivity(intent);
+            }
+
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see android.os.AsyncTask#onPreExecute()
+         */
+        @Override
+        protected void onPreExecute() {
+            statusText.setText("Opening a server socket");
+        }
+
+    }
+
+    public static boolean copyFile(InputStream inputStream, OutputStream out) {
+        byte buf[] = new byte[1024];
+        int len;
+        try {
+            while ((len = inputStream.read(buf)) != -1) {
+                out.write(buf, 0, len);
+
+            }
+            out.close();
+            inputStream.close();
+        } catch (IOException e) {
+            Log.d(WiFiDirectActivity.TAG, e.toString());
+            return false;
+        }
+        return true;
+    }
+
+}
diff --git a/samples/WiFiDirectDemo/src/com/example/android/wifidirect/DeviceListFragment.java b/samples/WiFiDirectDemo/src/com/example/android/wifidirect/DeviceListFragment.java
new file mode 100644
index 0000000..bfdbd6b
--- /dev/null
+++ b/samples/WiFiDirectDemo/src/com/example/android/wifidirect/DeviceListFragment.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.wifidirect;
+
+import android.app.ListFragment;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.net.wifi.p2p.WifiP2pConfig;
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pDeviceList;
+import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A ListFragment that displays available peers on discovery and requests the
+ * parent activity to handle user interaction events
+ */
+public class DeviceListFragment extends ListFragment implements PeerListListener {
+
+    private List<WifiP2pDevice> peers = new ArrayList<WifiP2pDevice>();
+    ProgressDialog progressDialog = null;
+    View mContentView = null;
+    private WifiP2pDevice device;
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        this.setListAdapter(new WiFiPeerListAdapter(getActivity(), R.layout.row_devices, peers));
+
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        mContentView = inflater.inflate(R.layout.device_list, null);
+        return mContentView;
+    }
+
+    /**
+     * @return this device
+     */
+    public WifiP2pDevice getDevice() {
+        return device;
+    }
+
+    private static String getDeviceStatus(int deviceStatus) {
+        Log.d(WiFiDirectActivity.TAG, "Peer status :" + deviceStatus);
+        switch (deviceStatus) {
+            case WifiP2pDevice.AVAILABLE:
+                return "Available";
+            case WifiP2pDevice.INVITED:
+                return "Invited";
+            case WifiP2pDevice.CONNECTED:
+                return "Connected";
+            case WifiP2pDevice.FAILED:
+                return "Failed";
+            case WifiP2pDevice.UNAVAILABLE:
+                return "Unavailable";
+            default:
+                return "Unknown";
+
+        }
+    }
+
+    /**
+     * Initiate a connection with the peer.
+     */
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+        WifiP2pDevice device = (WifiP2pDevice) getListAdapter().getItem(position);
+        ((DeviceActionListener) getActivity()).showDetails(device);
+    }
+
+    /**
+     * Array adapter for ListFragment that maintains WifiP2pDevice list.
+     */
+    private class WiFiPeerListAdapter extends ArrayAdapter<WifiP2pDevice> {
+
+        private List<WifiP2pDevice> items;
+
+        /**
+         * @param context
+         * @param textViewResourceId
+         * @param objects
+         */
+        public WiFiPeerListAdapter(Context context, int textViewResourceId,
+                List<WifiP2pDevice> objects) {
+            super(context, textViewResourceId, objects);
+            items = objects;
+
+        }
+
+        @Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            View v = convertView;
+            if (v == null) {
+                LayoutInflater vi = (LayoutInflater) getActivity().getSystemService(
+                        Context.LAYOUT_INFLATER_SERVICE);
+                v = vi.inflate(R.layout.row_devices, null);
+            }
+            WifiP2pDevice device = items.get(position);
+            if (device != null) {
+                TextView top = (TextView) v.findViewById(R.id.device_name);
+                TextView bottom = (TextView) v.findViewById(R.id.device_details);
+                if (top != null) {
+                    top.setText(device.deviceName);
+                }
+                if (bottom != null) {
+                    bottom.setText(getDeviceStatus(device.status));
+                }
+            }
+
+            return v;
+
+        }
+    }
+
+    /**
+     * Update UI for this device.
+     * 
+     * @param device WifiP2pDevice object
+     */
+    public void updateThisDevice(WifiP2pDevice device) {
+        this.device = device;
+        TextView view = (TextView) mContentView.findViewById(R.id.my_name);
+        view.setText(device.deviceName);
+        view = (TextView) mContentView.findViewById(R.id.my_status);
+        view.setText(getDeviceStatus(device.status));
+    }
+
+    @Override
+    public void onPeersAvailable(WifiP2pDeviceList peerList) {
+        if (progressDialog != null && progressDialog.isShowing()) {
+            progressDialog.dismiss();
+        }
+        peers.clear();
+        peers.addAll(peerList.getDeviceList());
+        ((WiFiPeerListAdapter) getListAdapter()).notifyDataSetChanged();
+        if (peers.size() == 0) {
+            Log.d(WiFiDirectActivity.TAG, "No devices found");
+            return;
+        }
+
+    }
+
+    public void clearPeers() {
+        peers.clear();
+        ((WiFiPeerListAdapter) getListAdapter()).notifyDataSetChanged();
+    }
+
+    /**
+     * 
+     */
+    public void onInitiateDiscovery() {
+        if (progressDialog != null && progressDialog.isShowing()) {
+            progressDialog.dismiss();
+        }
+        progressDialog = ProgressDialog.show(getActivity(), "Press back to cancel", "finding peers", true,
+                true, new DialogInterface.OnCancelListener() {
+
+                    @Override
+                    public void onCancel(DialogInterface dialog) {
+                        
+                    }
+                });
+    }
+
+    /**
+     * An interface-callback for the activity to listen to fragment interaction
+     * events.
+     */
+    public interface DeviceActionListener {
+
+        void showDetails(WifiP2pDevice device);
+
+        void cancelDisconnect();
+
+        void connect(WifiP2pConfig config);
+
+        void disconnect();
+    }
+
+}
diff --git a/samples/WiFiDirectDemo/src/com/example/android/wifidirect/FileTransferService.java b/samples/WiFiDirectDemo/src/com/example/android/wifidirect/FileTransferService.java
new file mode 100644
index 0000000..cfd3160
--- /dev/null
+++ b/samples/WiFiDirectDemo/src/com/example/android/wifidirect/FileTransferService.java
@@ -0,0 +1,86 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+package com.example.android.wifidirect;
+
+import android.app.IntentService;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.util.Log;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+/**
+ * A service that process each file transfer request i.e Intent by opening a
+ * socket connection with the WiFi Direct Group Owner and writing the file
+ */
+public class FileTransferService extends IntentService {
+
+    private static final int SOCKET_TIMEOUT = 5000;
+    public static final String ACTION_SEND_FILE = "com.example.android.wifidirect.SEND_FILE";
+    public static final String EXTRAS_FILE_PATH = "file_url";
+    public static final String EXTRAS_GROUP_OWNER_ADDRESS = "go_host";
+    public static final String EXTRAS_GROUP_OWNER_PORT = "go_port";
+
+    public FileTransferService(String name) {
+        super(name);
+    }
+
+    public FileTransferService() {
+        super("FileTransferService");
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.app.IntentService#onHandleIntent(android.content.Intent)
+     */
+    @Override
+    protected void onHandleIntent(Intent intent) {
+
+        Context context = getApplicationContext();
+        if (intent.getAction().equals(ACTION_SEND_FILE)) {
+            String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);
+            String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);
+            Socket socket = new Socket();
+            int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
+
+            try {
+                Log.d(WiFiDirectActivity.TAG, "Opening client socket - ");
+                socket.bind(null);
+                socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
+
+                Log.d(WiFiDirectActivity.TAG, "Client socket - " + socket.isConnected());
+                OutputStream stream = socket.getOutputStream();
+                ContentResolver cr = context.getContentResolver();
+                InputStream is = null;
+                try {
+                    is = cr.openInputStream(Uri.parse(fileUri));
+                } catch (FileNotFoundException e) {
+                    Log.d(WiFiDirectActivity.TAG, e.toString());
+                }
+                DeviceDetailFragment.copyFile(is, stream);
+                Log.d(WiFiDirectActivity.TAG, "Client: Data written");
+            } catch (IOException e) {
+                Log.e(WiFiDirectActivity.TAG, e.getMessage());
+            } finally {
+                if (socket != null) {
+                    if (socket.isConnected()) {
+                        try {
+                            socket.close();
+                        } catch (IOException e) {
+                            // Give up
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            }
+
+        }
+    }
+}
diff --git a/samples/WiFiDirectDemo/src/com/example/android/wifidirect/WiFiDirectActivity.java b/samples/WiFiDirectDemo/src/com/example/android/wifidirect/WiFiDirectActivity.java
new file mode 100644
index 0000000..2e51c3d
--- /dev/null
+++ b/samples/WiFiDirectDemo/src/com/example/android/wifidirect/WiFiDirectActivity.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.wifidirect;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.p2p.WifiP2pConfig;
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pManager;
+import android.net.wifi.p2p.WifiP2pManager.ActionListener;
+import android.net.wifi.p2p.WifiP2pManager.Channel;
+import android.net.wifi.p2p.WifiP2pManager.ChannelListener;
+import android.os.Bundle;
+import android.provider.Settings;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.widget.Toast;
+
+import com.example.android.wifidirect.DeviceListFragment.DeviceActionListener;
+
+/**
+ * An activity that uses WiFi Direct APIs to discover and connect with available
+ * devices. WiFi Direct APIs are asynchronous and rely on callback mechanism
+ * using interfaces to notify the application of operation success or failure.
+ * The application should also register a BroadcastReceiver for notification of
+ * WiFi state related events.
+ */
+public class WiFiDirectActivity extends Activity implements ChannelListener, DeviceActionListener {
+
+    public static final String TAG = "wifidirectdemo";
+    private WifiP2pManager manager;
+    private boolean isWifiP2pEnabled = false;
+    private boolean retryChannel = false;
+
+    private final IntentFilter intentFilter = new IntentFilter();
+    private Channel channel;
+    private BroadcastReceiver receiver = null;
+
+    /**
+     * @param isWifiP2pEnabled the isWifiP2pEnabled to set
+     */
+    public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled) {
+        this.isWifiP2pEnabled = isWifiP2pEnabled;
+    }
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+
+        // add necessary intent values to be matched.
+
+        intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
+        intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
+        intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
+        intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
+
+        manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
+        channel = manager.initialize(this, getMainLooper(), null);
+    }
+
+    /** register the BroadcastReceiver with the intent values to be matched */
+    @Override
+    public void onResume() {
+        super.onResume();
+        receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
+        registerReceiver(receiver, intentFilter);
+    }
+
+    @Override
+    public void onPause() {
+        super.onPause();
+        unregisterReceiver(receiver);
+    }
+
+    /**
+     * Remove all peers and clear all fields. This is called on
+     * BroadcastReceiver receiving a state change event.
+     */
+    public void resetData() {
+        DeviceListFragment fragmentList = (DeviceListFragment) getFragmentManager()
+                .findFragmentById(R.id.frag_list);
+        DeviceDetailFragment fragmentDetails = (DeviceDetailFragment) getFragmentManager()
+                .findFragmentById(R.id.frag_detail);
+        if (fragmentList != null) {
+            fragmentList.clearPeers();
+        }
+        if (fragmentDetails != null) {
+            fragmentDetails.resetViews();
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.action_items, menu);
+        return true;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
+     */
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.atn_direct_enable:
+                if (manager != null && channel != null) {
+
+                    // Since this is the system wireless settings activity, it's
+                    // not going to send us a result. We will be notified by
+                    // WiFiDeviceBroadcastReceiver instead.
+
+                    startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
+                } else {
+                    Log.e(TAG, "channel or manager is null");
+                }
+                return true;
+
+            case R.id.atn_direct_discover:
+                if (!isWifiP2pEnabled) {
+                    Toast.makeText(WiFiDirectActivity.this, R.string.p2p_off_warning,
+                            Toast.LENGTH_SHORT).show();
+                    return true;
+                }
+                final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
+                        .findFragmentById(R.id.frag_list);
+                fragment.onInitiateDiscovery();
+                manager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
+
+                    @Override
+                    public void onSuccess() {
+                        Toast.makeText(WiFiDirectActivity.this, "Discovery Initiated",
+                                Toast.LENGTH_SHORT).show();
+                    }
+
+                    @Override
+                    public void onFailure(int reasonCode) {
+                        Toast.makeText(WiFiDirectActivity.this, "Discovery Failed : " + reasonCode,
+                                Toast.LENGTH_SHORT).show();
+                    }
+                });
+                return true;
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+    }
+
+    @Override
+    public void showDetails(WifiP2pDevice device) {
+        DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
+                .findFragmentById(R.id.frag_detail);
+        fragment.showDetails(device);
+
+    }
+
+    @Override
+    public void connect(WifiP2pConfig config) {
+        manager.connect(channel, config, new ActionListener() {
+
+            @Override
+            public void onSuccess() {
+                // WiFiDirectBroadcastReceiver will notify us. Ignore for now.
+            }
+
+            @Override
+            public void onFailure(int reason) {
+                Toast.makeText(WiFiDirectActivity.this, "Connect failed. Retry.",
+                        Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+
+    @Override
+    public void disconnect() {
+        final DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
+                .findFragmentById(R.id.frag_detail);
+        fragment.resetViews();
+        manager.removeGroup(channel, new ActionListener() {
+
+            @Override
+            public void onFailure(int reasonCode) {
+                Log.d(TAG, "Disconnect failed. Reason :" + reasonCode);
+
+            }
+
+            @Override
+            public void onSuccess() {
+                fragment.getView().setVisibility(View.GONE);
+            }
+
+        });
+    }
+
+    @Override
+    public void onChannelDisconnected() {
+        // we will try once more
+        if (manager != null && !retryChannel) {
+            Toast.makeText(this, "Channel lost. Trying again", Toast.LENGTH_LONG).show();
+            resetData();
+            retryChannel = true;
+            manager.initialize(this, getMainLooper(), this);
+        } else {
+            Toast.makeText(this,
+                    "Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P.",
+                    Toast.LENGTH_LONG).show();
+        }
+    }
+
+    @Override
+    public void cancelDisconnect() {
+
+        /*
+         * A cancel abort request by user. Disconnect i.e. removeGroup if
+         * already connected. Else, request WifiP2pManager to abort the ongoing
+         * request
+         */
+        if (manager != null) {
+            final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
+                    .findFragmentById(R.id.frag_list);
+            if (fragment.getDevice() == null
+                    || fragment.getDevice().status == WifiP2pDevice.CONNECTED) {
+                disconnect();
+            } else if (fragment.getDevice().status == WifiP2pDevice.AVAILABLE
+                    || fragment.getDevice().status == WifiP2pDevice.INVITED) {
+
+                manager.cancelConnect(channel, new ActionListener() {
+
+                    @Override
+                    public void onSuccess() {
+                        Toast.makeText(WiFiDirectActivity.this, "Aborting connection",
+                                Toast.LENGTH_SHORT).show();
+                    }
+
+                    @Override
+                    public void onFailure(int reasonCode) {
+                        Toast.makeText(WiFiDirectActivity.this,
+                                "Connect abort request failed. Reason Code: " + reasonCode,
+                                Toast.LENGTH_SHORT).show();
+                    }
+                });
+            }
+        }
+
+    }
+}
diff --git a/samples/WiFiDirectDemo/src/com/example/android/wifidirect/WiFiDirectBroadcastReceiver.java b/samples/WiFiDirectDemo/src/com/example/android/wifidirect/WiFiDirectBroadcastReceiver.java
new file mode 100644
index 0000000..8bec5b4
--- /dev/null
+++ b/samples/WiFiDirectDemo/src/com/example/android/wifidirect/WiFiDirectBroadcastReceiver.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.wifidirect;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.net.NetworkInfo;
+import android.net.wifi.p2p.WifiP2pDevice;
+import android.net.wifi.p2p.WifiP2pManager;
+import android.net.wifi.p2p.WifiP2pManager.Channel;
+import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
+import android.util.Log;
+
+/**
+ * A BroadcastReceiver that notifies of important wifi p2p events.
+ */
+public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
+
+    private WifiP2pManager manager;
+    private Channel channel;
+    private WiFiDirectActivity activity;
+
+    /**
+     * @param manager WifiP2pManager system service
+     * @param channel Wifi p2p channel
+     * @param activity activity associated with the receiver
+     */
+    public WiFiDirectBroadcastReceiver(WifiP2pManager manager, Channel channel,
+            WiFiDirectActivity activity) {
+        super();
+        this.manager = manager;
+        this.channel = channel;
+        this.activity = activity;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.content.BroadcastReceiver#onReceive(android.content.Context,
+     * android.content.Intent)
+     */
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        String action = intent.getAction();
+        if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
+
+            // UI update to indicate wifi p2p status.
+            int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
+            if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
+                // Wifi Direct mode is enabled
+                activity.setIsWifiP2pEnabled(true);
+            } else {
+                activity.setIsWifiP2pEnabled(false);
+                activity.resetData();
+
+            }
+            Log.d(WiFiDirectActivity.TAG, "P2P state changed - " + state);
+        } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
+
+            // request available peers from the wifi p2p manager. This is an
+            // asynchronous call and the calling activity is notified with a
+            // callback on PeerListListener.onPeersAvailable()
+            if (manager != null) {
+                manager.requestPeers(channel, (PeerListListener) activity.getFragmentManager()
+                        .findFragmentById(R.id.frag_list));
+            }
+            Log.d(WiFiDirectActivity.TAG, "P2P peers changed");
+        } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
+
+            if (manager == null) {
+                return;
+            }
+
+            NetworkInfo networkInfo = (NetworkInfo) intent
+                    .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
+
+            if (networkInfo.isConnected()) {
+
+                // we are connected with the other device, request connection
+                // info to find group owner IP
+
+                DeviceDetailFragment fragment = (DeviceDetailFragment) activity
+                        .getFragmentManager().findFragmentById(R.id.frag_detail);
+                manager.requestConnectionInfo(channel, fragment);
+            } else {
+                // It's a disconnect
+                activity.resetData();
+            }
+        } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
+            DeviceListFragment fragment = (DeviceListFragment) activity.getFragmentManager()
+                    .findFragmentById(R.id.frag_list);
+            fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra(
+                    WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
+
+        }
+    }
+}
diff --git a/sdk/images_armeabi-v7a_source.properties b/sdk/images_armeabi-v7a_source.properties
index 50d4054..aa7d1aa 100644
--- a/sdk/images_armeabi-v7a_source.properties
+++ b/sdk/images_armeabi-v7a_source.properties
@@ -1,7 +1,6 @@
 Pkg.Desc=Android SDK Platform 4.0
 Pkg.UserSrc=false
-Platform.Version=4.0
 Pkg.Revision=1
 AndroidVersion.ApiLevel=14
-SystemImage.Abi=armeabi-v7a
 #AndroidVersion.CodeName=
+SystemImage.Abi=armeabi-v7a
diff --git a/sdk/images_armeabi_source.properties b/sdk/images_armeabi_source.properties
index 06cf392..192ecde 100644
--- a/sdk/images_armeabi_source.properties
+++ b/sdk/images_armeabi_source.properties
@@ -1,7 +1,6 @@
 Pkg.Desc=Android SDK Platform 4.0
 Pkg.UserSrc=false
-Platform.Version=4.0
 Pkg.Revision=1
 AndroidVersion.ApiLevel=14
-SystemImage.Abi=armeabi
 #AndroidVersion.CodeName=
+SystemImage.Abi=armeabi
diff --git a/sdk/images_x86_source.properties b/sdk/images_x86_source.properties
index 199f5c5..caccb2d 100644
--- a/sdk/images_x86_source.properties
+++ b/sdk/images_x86_source.properties
@@ -1,7 +1,6 @@
 Pkg.Desc=Android SDK Platform 4.0
 Pkg.UserSrc=false
-Platform.Version=4.0
 Pkg.Revision=1
 AndroidVersion.ApiLevel=14
-SystemImage.Abi=x86
 #AndroidVersion.CodeName=
+SystemImage.Abi=x86
diff --git a/sdk/platform_source.properties b/sdk/platform_source.properties
index 356fc97..5e3ef13 100644
--- a/sdk/platform_source.properties
+++ b/sdk/platform_source.properties
@@ -1,9 +1,8 @@
 Pkg.Desc=Android SDK Platform 4.0
 Pkg.UserSrc=false
-Platform.IncludedAbi=armeabi
 Platform.Version=4.0
 Pkg.Revision=1
-Layoutlib.Api=4
-Layoutlib.Revision=1
 AndroidVersion.ApiLevel=14
 #AndroidVersion.CodeName=
+Layoutlib.Api=7
+Layoutlib.Revision=1
diff --git a/sdk/source_source.properties b/sdk/source_source.properties
new file mode 100644
index 0000000..7cb1d33
--- /dev/null
+++ b/sdk/source_source.properties
@@ -0,0 +1,4 @@
+Pkg.UserSrc=false
+Pkg.Revision=1
+AndroidVersion.ApiLevel=14
+#AndroidVersion.CodeName=
diff --git a/sdk/support_source.properties b/sdk/support_source.properties
index cd3a0b0..16d5cd8 100644
--- a/sdk/support_source.properties
+++ b/sdk/support_source.properties
@@ -1,4 +1,6 @@
 Pkg.UserSrc=false
 Pkg.Revision=4
+Extra.Vendor=android
+Extra.Path=support
 Extra.OldPaths=compatibility
 
diff --git a/sdk_overlay/frameworks/base/core/res/res/values/config.xml b/sdk_overlay/frameworks/base/core/res/res/values/config.xml
index 3296ed1..22cc16e 100644
--- a/sdk_overlay/frameworks/base/core/res/res/values/config.xml
+++ b/sdk_overlay/frameworks/base/core/res/res/values/config.xml
@@ -23,6 +23,5 @@
     <!-- Component name of the service providing geocoder API support. -->
     <string name="config_geocodeProvider">com.google.android.location.GeocodeProvider</string>
 
-    <!-- This device is not "voice capable"; it's data-only. -->
-    <bool name="config_voice_capable">false</bool>
+    <bool name="config_voice_capable">true</bool>
 </resources>
diff --git a/tools/emulator/opengl/host/include/libOpenglRender/IOStream.h b/tools/emulator/opengl/host/include/libOpenglRender/IOStream.h
index 41d8023..445ec17 100644
--- a/tools/emulator/opengl/host/include/libOpenglRender/IOStream.h
+++ b/tools/emulator/opengl/host/include/libOpenglRender/IOStream.h
@@ -34,6 +34,7 @@
     virtual int commitBuffer(size_t size) = 0;
     virtual const unsigned char *readFully( void *buf, size_t len) = 0;
     virtual const unsigned char *read( void *buf, size_t *inout_len) = 0;
+    virtual int writeFully(const void* buf, size_t len) = 0;
 
     virtual ~IOStream() {
 
@@ -82,6 +83,7 @@
         return readFully(buf, len);
     }
 
+
 private:
     unsigned char *m_buf;
     size_t m_bufsize;
diff --git a/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp b/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp
index 9e95604..4265301 100644
--- a/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp
+++ b/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp
@@ -21,6 +21,15 @@
 #include <errno.h>
 #include <sys/types.h>
 
+/* Define this to 1 to enable support for the 'isLarge' variable flag
+ * that instructs the encoder to send large data buffers by a direct
+ * write through the pipe (i.e. without copying it into a temporary
+ * buffer. This has definite performance benefits when using a QEMU Pipe.
+ *
+ * Set to 0 otherwise.
+ */
+#define WITH_LARGE_SUPPORT  1
+
 EntryPoint * ApiGen::findEntryByName(const std::string & name)
 {
     EntryPoint * entry = NULL;
@@ -338,6 +347,104 @@
     return 0;
 }
 
+// Format the byte length expression for a given variable into a user-provided buffer
+// If the variable type is not a pointer, this is simply its size as a decimal constant
+// If the variable is a pointer, this will be an expression provided by the .attrib file
+// through the 'len' attribute.
+//
+// Returns 1 if the variable is a pointer, 0 otherwise
+//
+static int getVarEncodingSizeExpression(Var&  var, EntryPoint* e, char* buff, size_t bufflen)
+{
+    int ret = 0;
+    if (!var.isPointer()) {
+        snprintf(buff, bufflen, "%u", (unsigned int) var.type()->bytes());
+    } else {
+        ret = 1;
+        const char* lenExpr = var.lenExpression().c_str();
+        const char* varname = var.name().c_str();
+        if (e != NULL && lenExpr[0] == '\0') {
+            fprintf(stderr, "%s: data len is undefined for '%s'\n",
+                    e->name().c_str(), varname);
+        }
+        if (var.nullAllowed()) {
+            snprintf(buff, bufflen, "((%s != NULL) ? %s : 0)", varname, lenExpr);
+        } else {
+            snprintf(buff, bufflen, "%s", lenExpr);
+        }
+    }
+    return ret;
+}
+
+static int writeVarEncodingSize(Var& var, FILE* fp)
+{
+    int ret = 0;
+    if (!var.isPointer()) {
+        fprintf(fp, "%u", (unsigned int) var.type()->bytes());
+    } else {
+        ret = 1;
+        fprintf(fp, "__size_%s", var.name().c_str());
+    }
+    return ret;
+}
+
+
+
+static void writeVarEncodingExpression(Var& var, FILE* fp)
+{
+    const char* varname = var.name().c_str();
+
+    if (var.isPointer()) {
+        // encode a pointer header
+        fprintf(fp, "\t*(unsigned int *)(ptr) = __size_%s; ptr += 4;\n", varname);
+
+        Var::PointerDir dir = var.pointerDir();
+        if (dir == Var::POINTER_INOUT || dir == Var::POINTER_IN) {
+            if (var.nullAllowed()) {
+                fprintf(fp, "\tif (%s != NULL) ", varname);
+            } else {
+                fprintf(fp, "\t");
+            }
+
+            if (var.packExpression().size() != 0) {
+                fprintf(fp, "%s;", var.packExpression().c_str());
+            } else {
+                fprintf(fp, "memcpy(ptr, %s, __size_%s);",
+                        varname, varname);
+            }
+
+            fprintf(fp, "ptr += __size_%s;\n", varname);
+        }
+    } else {
+        // encode a non pointer variable
+        if (!var.isVoid()) {
+            fprintf(fp, "\t*(%s *) (ptr) = %s; ptr += %u;\n",
+                    var.type()->name().c_str(), varname,
+                    (uint) var.type()->bytes());
+        }
+    }
+}
+
+#if WITH_LARGE_SUPPORT
+static void writeVarLargeEncodingExpression(Var& var, FILE* fp)
+{
+    const char* varname = var.name().c_str();
+
+    fprintf(fp, "\tstream->writeFully(&__size_%s,4);\n", varname);
+    if (var.nullAllowed()) {
+        fprintf(fp, "\tif (%s != NULL) ", varname);
+    } else {
+        fprintf(fp, "\t");
+    }
+    if (var.writeExpression() != "") {
+        fprintf(fp, "%s", var.writeExpression().c_str());
+    } else {
+        fprintf(fp, "stream->writeFully(%s, __size_%s)", varname, varname);
+    }
+    fprintf(fp, ";\n");
+}
+#endif /* WITH_LARGE_SUPPORT */
+
 int ApiGen::genEncoderImpl(const std::string &filename)
 {
     FILE *fp = fopen(filename.c_str(), "wt");
@@ -368,46 +475,139 @@
         fprintf(fp, "{\n");
 
 //      fprintf(fp, "\n\tDBG(\">>>> %s\\n\");\n", e->name().c_str());
-        fprintf(fp, "\n\t%s *ctx = (%s *)self;\n\n",
+        fprintf(fp, "\n\t%s *ctx = (%s *)self;\n",
                 classname.c_str(),
                 classname.c_str());
-
-        // size calculation ;
-        fprintf(fp, "\t size_t packetSize = ");
-
+        fprintf(fp, "\tIOStream *stream = ctx->m_stream;\n\n");
         VarsArray & evars = e->vars();
+        size_t  maxvars = evars.size();
+        size_t  j;
+
+        char    buff[256];
+
+        // Define the __size_XXX variables that contain the size of data
+        // associated with pointers.
+        for (j = 0; j < maxvars; j++) {
+            Var& var = evars[j];
+
+            if (!var.isPointer())
+                continue;
+
+            const char* varname = var.name().c_str();
+            fprintf(fp, "\tconst unsigned int __size_%s = ", varname);
+
+            getVarEncodingSizeExpression(var, e, buff, sizeof(buff));
+            fprintf(fp, "%s;\n", buff);
+        }
+
+#if WITH_LARGE_SUPPORT
+        // We need to take care of 'isLarge' variable in a special way
+        // Anything before an isLarge variable can be packed into a single
+        // buffer, which is then commited. Each isLarge variable is a pointer
+        // to data that can be written to directly through the pipe, which
+        // will be instant when using a QEMU pipe
+
+        size_t  nvars   = 0;
+        size_t  npointers = 0;
+
+        // First, compute the total size, 8 bytes for the opcode + payload size
+        fprintf(fp, "\t unsigned char *ptr;\n");
+        fprintf(fp, "\t const size_t packetSize = 8");
+
+        for (j = 0; j < maxvars; j++) {
+            fprintf(fp, " + ");
+            npointers += writeVarEncodingSize(evars[j], fp);
+        }
+        if (npointers > 0) {
+            fprintf(fp, " + %u*4", npointers);
+        }
+        fprintf(fp, ";\n");
+
+        // We need to divide the packet into fragments. Each fragment contains
+        // either copied arguments to a temporary buffer, or direct writes for
+        // large variables.
+        //
+        // The first fragment must also contain the opcode+payload_size
+        //
+        nvars = 0;
+        while (nvars < maxvars || maxvars == 0) {
+
+            // Skip over non-large fields
+            for (j = nvars; j < maxvars; j++) {
+                if (evars[j].isLarge())
+                    break;
+            }
+
+            // Write a fragment if needed.
+            if (nvars == 0 || j > nvars) {
+                const char* plus = "";
+
+                if (nvars == 0 && j == maxvars) {
+                    // Simple shortcut for the common case where we don't have large variables;
+                    fprintf(fp, "\tptr = stream->alloc(packetSize);\n");
+
+                } else {
+                    // allocate buffer from the stream until the first large variable
+                    fprintf(fp, "\tptr = stream->alloc(");
+                    plus = "";
+
+                    if (nvars == 0) {
+                        fprintf(fp,"8"); plus = " + ";
+                    }
+                    if (j > nvars) {
+                        npointers = 0;
+                        for (j = nvars; j < maxvars && !evars[j].isLarge(); j++) {
+                            fprintf(fp, "%s", plus); plus = " + ";
+                            npointers += writeVarEncodingSize(evars[j], fp);
+                        }
+                        if (npointers > 0) {
+                            fprintf(fp, "%s%u*4", plus, npointers); plus = " + ";
+                        }
+                    }
+                    fprintf(fp,");\n");
+                }
+
+                // encode packet header if needed.
+                if (nvars == 0) {
+                    fprintf(fp, "\t*(unsigned int *)(ptr) = OP_%s; ptr += 4;\n", e->name().c_str());
+                    fprintf(fp, "\t*(unsigned int *)(ptr) = (unsigned int) packetSize; ptr += 4;\n");
+                }
+
+                if (maxvars == 0)
+                    break;
+
+                // encode non-large fields in this fragment
+                for (j = nvars; j < maxvars && !evars[j].isLarge(); j++) {
+                    writeVarEncodingExpression(evars[j],fp);
+                }
+
+                // Ensure the fragment is commited if it is followed by a large variable
+                if (j < maxvars) {
+                    fprintf(fp, "\tstream->flush();\n");
+                }
+            }
+
+            // If we have one or more large variables, write them directly.
+            // As size + data
+            for ( ; j < maxvars && evars[j].isLarge(); j++) {
+                writeVarLargeEncodingExpression(evars[j], fp);
+            }
+
+            nvars = j;
+        }
+
+#else /* !WITH_LARGE_SUPPORT */
         size_t nvars = evars.size();
         size_t npointers = 0;
+        fprintf(fp, "\t const size_t packetSize = 8");
         for (size_t j = 0; j < nvars; j++) {
-            fprintf(fp, "%s ", j == 0 ? "" : " +");
-            if (evars[j].isPointer()) {
-                npointers++;
-
-                if (evars[j].lenExpression() == "") {
-                    fprintf(stderr, "%s: data len is undefined for '%s'\n",
-                            e->name().c_str(), evars[j].name().c_str());
-                }
-
-                if (evars[j].nullAllowed()) {
-                    fprintf(fp, "(%s != NULL ? %s : 0)",
-                            evars[j].name().c_str(),
-                            evars[j].lenExpression().c_str());
-                } else {
-                    if (evars[j].pointerDir() == Var::POINTER_IN ||
-                        evars[j].pointerDir() == Var::POINTER_INOUT) {
-                        fprintf(fp, "%s", evars[j].lenExpression().c_str());
-                    } else {
-                        fprintf(fp, "0");
-                    }
-                }
-            } else {
-                fprintf(fp, "%u", (unsigned int) evars[j].type()->bytes());
-            }
+            npointers += getVarEncodingSizeExpression(evars[j],e,buff,sizeof(buff));
+            fprintf(fp, " + %s", buff);
         }
-        fprintf(fp, " %s 8 + %u * 4;\n", nvars != 0 ? "+" : "", (unsigned int) npointers);
+        fprintf(fp, " + %u * 4;\n", (unsigned int) npointers);
 
         // allocate buffer from the stream;
-        fprintf(fp, "\t unsigned char *ptr = ctx->m_stream->alloc(packetSize);\n\n");
+        fprintf(fp, "\t unsigned char *ptr = stream->alloc(packetSize);\n\n");
 
         // encode into the stream;
         fprintf(fp, "\t*(unsigned int *)(ptr) = OP_%s; ptr += 4;\n",  e->name().c_str());
@@ -415,62 +615,23 @@
 
         // out variables
         for (size_t j = 0; j < nvars; j++) {
-            if (evars[j].isPointer()) {
-                // encode a pointer header
-                if (evars[j].nullAllowed()) {
-                    fprintf(fp, "\t*(unsigned int *)(ptr) = (%s != NULL) ? %s : 0; ptr += 4; \n",
-                            evars[j].name().c_str(), evars[j].lenExpression().c_str());
-                } else {
-                    fprintf(fp, "\t*(unsigned int *)(ptr) = %s; ptr += 4; \n",
-                            evars[j].lenExpression().c_str());
-                }
-
-                Var::PointerDir dir = evars[j].pointerDir();
-                if (dir == Var::POINTER_INOUT || dir == Var::POINTER_IN) {
-                    if (evars[j].nullAllowed()) {
-                        fprintf(fp, "\tif (%s != NULL) ", evars[j].name().c_str());
-                    } else {
-                        fprintf(fp, "\t");
-                    }
-
-                    if (evars[j].packExpression().size() != 0) {
-                        fprintf(fp, "%s;", evars[j].packExpression().c_str());
-                    } else {
-                        fprintf(fp, "memcpy(ptr, %s, %s);",
-                                evars[j].name().c_str(),
-                                evars[j].lenExpression().c_str());
-                    }
-
-                    if (evars[j].nullAllowed()) {
-                        fprintf(fp, "ptr += %s == NULL ? 0 : %s; \n", evars[j].name().c_str(), evars[j].lenExpression().c_str());
-                    } else {
-                        fprintf(fp, "ptr += %s;\n", evars[j].lenExpression().c_str());
-                    }
-                }
-            } else {
-                // encode a non pointer variable
-                if (!evars[j].isVoid()) {
-                    fprintf(fp, "\t*(%s *) (ptr) = %s; ptr += %u;\n",
-                            evars[j].type()->name().c_str(), evars[j].name().c_str(),
-                            (uint) evars[j].type()->bytes());
-                }
-            }
+            writeVarEncodingExpression(evars[j], fp);
         }
+#endif /* !WITH_LARGE_SUPPORT */
+
         // in variables;
         for (size_t j = 0; j < nvars; j++) {
             if (evars[j].isPointer()) {
                 Var::PointerDir dir = evars[j].pointerDir();
                 if (dir == Var::POINTER_INOUT || dir == Var::POINTER_OUT) {
+                    const char* varname = evars[j].name().c_str();
                     if (evars[j].nullAllowed()) {
-                        fprintf(fp, "\tif (%s != NULL) ctx->m_stream->readback(%s, %s);\n",
-                                evars[j].name().c_str(),
-                                evars[j].name().c_str(),
-                                evars[j].lenExpression().c_str());
+                        fprintf(fp, "\tif (%s != NULL) ",varname);
                     } else {
-                        fprintf(fp, "\tctx->m_stream->readback(%s, %s);\n",
-                                evars[j].name().c_str(),
-                                evars[j].lenExpression().c_str());
+                        fprintf(fp, "\t");
                     }
+                    fprintf(fp, "stream->readback(%s, __size_%s);\n",
+                            varname, varname);
                 }
             }
         }
@@ -482,7 +643,7 @@
             fprintf(fp, "\t return NULL;\n");
         } else if (e->retval().type()->name() != "void") {
             fprintf(fp, "\n\t%s retval;\n", e->retval().type()->name().c_str());
-            fprintf(fp, "\tctx->m_stream->readback(&retval, %u);\n",(uint) e->retval().type()->bytes());
+            fprintf(fp, "\tstream->readback(&retval, %u);\n",(uint) e->retval().type()->bytes());
             fprintf(fp, "\treturn retval;\n");
         }
         fprintf(fp, "}\n\n");
diff --git a/tools/emulator/opengl/host/tools/emugen/EntryPoint.cpp b/tools/emulator/opengl/host/tools/emugen/EntryPoint.cpp
index 413b56a..43b904b 100644
--- a/tools/emulator/opengl/host/tools/emugen/EntryPoint.cpp
+++ b/tools/emulator/opengl/host/tools/emugen/EntryPoint.cpp
@@ -119,7 +119,7 @@
         fprintf(stderr, "UNKNOWN retval: %s\n", linestr.c_str());
     }
 
-    m_retval.init(std::string(""), theType, std::string(""), Var::POINTER_OUT, std::string(""));
+    m_retval.init(std::string(""), theType, std::string(""), Var::POINTER_OUT, std::string(""), std::string(""));
 
     // function name
     m_name = getNextToken(linestr, pos, &last, ",)");
@@ -146,7 +146,7 @@
                 varname = oss.str();
             }
 
-            m_vars.push_back(Var(varname, v, std::string(""), Var::POINTER_IN, ""));
+            m_vars.push_back(Var(varname, v, std::string(""), Var::POINTER_IN, "", ""));
         }
         pos = last + 1;
     }
@@ -286,22 +286,36 @@
                     (unsigned int)lc, varname.c_str(), name().c_str());
             return -2;
         }
-        pos = last;
-        std::string flag = getNextToken(line, pos, &last, WHITESPACE);
-        if (flag.size() == 0) {
-            fprintf(stderr, "ERROR: %u: missing flag\n", (unsigned int) lc);
-            return -3;
-        }
-
-        if (flag == "nullAllowed") {
-            if (v->isPointer()) {
-                v->setNullAllowed(true);
-            } else {
-                fprintf(stderr, "WARNING: %u: setting nullAllowed for non-pointer variable %s\n",
-                        (unsigned int) lc, v->name().c_str());
+        int count = 0;
+        for (;;) {
+            pos = last;
+            std::string flag = getNextToken(line, pos, &last, WHITESPACE);
+            if (flag.size() == 0) {
+                if (count == 0) {
+                    fprintf(stderr, "ERROR: %u: missing flag\n", (unsigned int) lc);
+                    return -3;
+                }
+                break;
             }
-        } else {
-            fprintf(stderr, "WARNING: %u: unknow flag %s\n", (unsigned int)lc, flag.c_str());
+            count++;
+
+            if (flag == "nullAllowed") {
+                if (v->isPointer()) {
+                    v->setNullAllowed(true);
+                } else {
+                    fprintf(stderr, "WARNING: %u: setting nullAllowed for non-pointer variable %s\n",
+                            (unsigned int) lc, v->name().c_str());
+                }
+            } else if (flag == "isLarge") {
+                if (v->isPointer()) {
+                    v->setIsLarge(true);
+                } else {
+                    fprintf(stderr, "WARNING: %u: setting isLarge flag for a non-pointer variable %s\n",
+                            (unsigned int) lc, v->name().c_str());
+                }
+            } else {
+                fprintf(stderr, "WARNING: %u: unknow flag %s\n", (unsigned int)lc, flag.c_str());
+            }
         }
     } else if (token == "custom_pack") {
         pos = last;
@@ -320,6 +334,23 @@
         // set the size expression into var
         pos = last;
         v->setPackExpression(line.substr(pos));
+    } else if (token == "custom_write") {
+        pos = last;
+        std::string varname = getNextToken(line, pos, &last, WHITESPACE);
+
+        if (varname.size() == 0) {
+            fprintf(stderr, "ERROR: %u: Missing variable name in 'custom_write' attribute\n", (unsigned int)lc);
+            return -1;
+        }
+        Var * v = var(varname);
+        if (v == NULL) {
+            fprintf(stderr, "ERROR: %u: variable %s is not a parameter of %s\n",
+                    (unsigned int)lc, varname.c_str(), name().c_str());
+            return -2;
+        }
+        // set the size expression into var
+        pos = last;
+        v->setWriteExpression(line.substr(pos));
     } else if (token == "flag") {
         pos = last;
         std::string flag = getNextToken(line, pos, &last, WHITESPACE);
diff --git a/tools/emulator/opengl/host/tools/emugen/README b/tools/emulator/opengl/host/tools/emugen/README
index 4d2c28d..5df11a3 100644
--- a/tools/emulator/opengl/host/tools/emugen/README
+++ b/tools/emulator/opengl/host/tools/emugen/README
@@ -313,7 +313,10 @@
 
  var_flag 
  	 description : set variable flags
- 	 format: var_flag <varname> < nullAllowed | ... >
+ 	 format: var_flag <varname> < nullAllowed | isLarge | ... >
+
+        nullAllowed -> for pointer variables, indicates that NULL is a valid value
+        isLarge     -> for pointer variables, indicates that the data should be sent without an intermediate copy
 
  flag
 	description: set entry point flag; 
diff --git a/tools/emulator/opengl/host/tools/emugen/Var.h b/tools/emulator/opengl/host/tools/emugen/Var.h
index c9735c7..322c66a 100644
--- a/tools/emulator/opengl/host/tools/emugen/Var.h
+++ b/tools/emulator/opengl/host/tools/emugen/Var.h
@@ -30,7 +30,9 @@
         m_lenExpression(""),
         m_pointerDir(POINTER_IN),
         m_nullAllowed(false),
+        m_isLarge(false),
         m_packExpression(""),
+        m_writeExpression(""),
         m_paramCheckExpression("")
 
     {
@@ -40,26 +42,33 @@
         const VarType * vartype,
         const std::string & lenExpression,
         PointerDir dir,
-        const std::string &packExpression) :
+        const std::string &packExpression,
+        const std::string &writeExpression) :
         m_name(name),
         m_type(const_cast<VarType *>(vartype)),
         m_lenExpression(lenExpression),
         m_pointerDir(dir),
         m_nullAllowed(false),
+        m_isLarge(false),
         m_packExpression(packExpression),
-		m_paramCheckExpression("")	
+        m_writeExpression(writeExpression),
+	m_paramCheckExpression("")
     {
     }
 
     void init(const std::string name, const VarType * vartype,
               std::string lenExpression,
-              PointerDir dir, std::string packExpression) {
+              PointerDir dir,
+              std::string packExpression,
+              std::string writeExpression) {
         m_name = name;
         m_type = vartype;
         m_lenExpression = lenExpression;
         m_packExpression = packExpression;
+        m_writeExpression = writeExpression;
         m_pointerDir = dir;
         m_nullAllowed = false;
+        m_isLarge = false;
 
     }
 
@@ -69,14 +78,18 @@
     bool isVoid() const { return ((m_type->bytes() == 0) && (!m_type->isPointer())); }
     const std::string & lenExpression() const { return m_lenExpression; }
     const std::string & packExpression() const { return(m_packExpression); }
+    const std::string & writeExpression() const { return(m_writeExpression); }
     const std::string & paramCheckExpression() const { return m_paramCheckExpression; }
     void setLenExpression(const std::string & lenExpression) { m_lenExpression = lenExpression; }
     void setPackExpression(const std::string & packExpression) { m_packExpression = packExpression; }
+    void setWriteExpression(const std::string & writeExpression) { m_writeExpression = writeExpression; }
     void setParamCheckExpression(const std::string & paramCheckExpression) { m_paramCheckExpression = paramCheckExpression; }
     void setPointerDir(PointerDir dir) { m_pointerDir = dir; }
     PointerDir pointerDir() { return m_pointerDir; }
     void setNullAllowed(bool state) { m_nullAllowed = state; }
+    void setIsLarge(bool state) { m_isLarge = state; }
     bool nullAllowed() const { return m_nullAllowed; }
+    bool isLarge() const { return m_isLarge; }
     void printType(FILE *fp) { fprintf(fp, "%s", m_type->name().c_str()); }
     void printTypeName(FILE *fp) { printType(fp); fprintf(fp, " %s", m_name.c_str()); }
 
@@ -87,7 +100,9 @@
     std::string m_lenExpression; // an expression to calcualte a pointer data size
     PointerDir m_pointerDir;
     bool m_nullAllowed;
+    bool m_isLarge;
     std::string m_packExpression; // an expression to pack data into the stream
+    std::string m_writeExpression; // an expression to write data into the stream
     std::string m_paramCheckExpression; //an expression to check parameter value
 
 };
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp
index 244cfbb..ddc56d0 100644
--- a/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.cpp
@@ -85,13 +85,18 @@
 
 int SocketStream::commitBuffer(size_t size)
 {
+    return writeFully(m_buf, size);
+}
+
+int SocketStream::writeFully(const void* buffer, size_t size)
+{
     if (!valid()) return -1;
 
     size_t res = size;
     int retval = 0;
 
     while (res > 0) {
-        ssize_t stat = ::send(m_sock, (const char *)(m_buf) + (size - res), res, 0);
+        ssize_t stat = ::send(m_sock, (const char *)buffer + (size - res), res, 0);
         if (stat < 0) {
             if (errno != EINTR) {
                 retval =  stat;
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h b/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h
index c54dea7..3a501b4 100644
--- a/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/SocketStream.h
@@ -37,6 +37,7 @@
 
     bool valid() { return m_sock >= 0; }
     virtual int recv(void *buf, size_t len);
+    virtual int writeFully(const void *buf, size_t len);
 
 protected:
     int            m_sock;
@@ -44,7 +45,6 @@
     unsigned char *m_buf;
 
     SocketStream(int sock, size_t bufSize);
-    int writeFully(const void *buf, size_t len);
 };
 
 #endif /* __SOCKET_STREAM_H */
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp
index b0702a7..ae70598 100644
--- a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.cpp
@@ -16,6 +16,7 @@
 #include "glUtils.h"
 #include <string.h>
 #include "ErrorLog.h"
+#include <IOStream.h>
 
 size_t glSizeof(GLenum type)
 {
@@ -344,6 +345,25 @@
     }
 }
 
+void glUtilsWritePackPointerData(void* _stream, unsigned char *src,
+                                 int size, GLenum type, unsigned int stride,
+                                 unsigned int datalen)
+{
+    IOStream* stream = reinterpret_cast<IOStream*>(_stream);
+
+    unsigned int  vsize = size * glSizeof(type);
+    if (stride == 0) stride = vsize;
+
+    if (stride == vsize) {
+        stream->writeFully(src, datalen);
+    } else {
+        for (unsigned int i = 0; i < datalen; i += vsize) {
+            stream->writeFully(src, (size_t)vsize);
+            src += stride;
+        }
+    }
+}
+
 int glUtilsPixelBitSize(GLenum format, GLenum type)
 {
     int components = 0;
diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h
index c66c568..f8857f1 100644
--- a/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h
+++ b/tools/emulator/opengl/shared/OpenglCodecCommon/glUtils.h
@@ -51,6 +51,9 @@
     void   glUtilsPackPointerData(unsigned char *dst, unsigned char *str,
                            int size, GLenum type, unsigned int stride,
                            unsigned int datalen);
+    void glUtilsWritePackPointerData(void* stream, unsigned char *src,
+                                    int size, GLenum type, unsigned int stride,
+                                    unsigned int datalen);
     int glUtilsPixelBitSize(GLenum format, GLenum type);
     void   glUtilsPackStrings(char *ptr, char **strings, GLint *length, GLsizei count);
     int glUtilsCalcShaderSourceLen(char **strings, GLint *length, GLsizei count);
diff --git a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp
index 6d12fe3..43391f0 100644
--- a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp
+++ b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp
@@ -544,7 +544,7 @@
     m_glBufferData_enc = set_glBufferData(s_glBufferData);
     m_glBufferSubData_enc = set_glBufferSubData(s_glBufferSubData);
     m_glDeleteBuffers_enc = set_glDeleteBuffers(s_glDeleteBuffers);
-    
+
     m_glEnableClientState_enc = set_glEnableClientState(s_glEnableClientState);
     m_glDisableClientState_enc = set_glDisableClientState(s_glDisableClientState);
     m_glIsEnabled_enc = set_glIsEnabled(s_glIsEnabled);
@@ -558,7 +558,7 @@
 
 GLEncoder::~GLEncoder()
 {
-    delete m_compressedTextureFormats;
+    delete [] m_compressedTextureFormats;
 }
 
 size_t GLEncoder::pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack)
diff --git a/tools/emulator/opengl/system/GLESv1_enc/gl.attrib b/tools/emulator/opengl/system/GLESv1_enc/gl.attrib
index fed0f7a..9b84f89 100644
--- a/tools/emulator/opengl/system/GLESv1_enc/gl.attrib
+++ b/tools/emulator/opengl/system/GLESv1_enc/gl.attrib
@@ -240,7 +240,7 @@
 glTexImage2D
 	dir pixels in
 	len pixels pixelDataSize(self, width, height, format, type, 0)
-	var_flag pixels nullAllowed
+	var_flag pixels nullAllowed isLarge
 
 #void glTexParameteriv(GLenum target, GLenum pname, GLint *params)
 glTexParameteriv
@@ -253,6 +253,7 @@
 #void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
 glTexSubImage2D
 	len pixels pixelDataSize(self, width, height, format, type, 0)
+        var_flag pixels isLarge
 
 #void glVertexPointer(GLint size, GLenum type, GLsizei stride, GLvoid *pointer)
 # we treat the pointer as an offset to a VBO
diff --git a/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib
index 538c453..7fe9a66 100644
--- a/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib
+++ b/tools/emulator/opengl/system/GLESv2_enc/gl2.attrib
@@ -9,20 +9,22 @@
 #void glBufferData(GLenum target, GLsizeiptr size, GLvoid *data, GLenum usage)
 glBufferData
 	len data size
-	var_flag data nullAllowed
+	var_flag data nullAllowed isLarge
 
 #void glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data)
 glBufferSubData
 	len data size
+        var_flag data isLarge
 
 #void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLvoid *data)
 glCompressedTexImage2D
 	len data imageSize
-    var_flag data nullAllowed
+    var_flag data nullAllowed isLarge
 
 #void glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLvoid *data)
 glCompressedTexSubImage2D
 	len data imageSize
+        var_flag data isLarge
 
 #void glDeleteBuffers(GLsizei n, GLuint *buffers)
 glDeleteBuffers
@@ -243,7 +245,7 @@
 glTexImage2D
 	dir pixels in
 	len pixels pixelDataSize(self, width, height, format, type, 0)
-	var_flag pixels nullAllowed
+	var_flag pixels nullAllowed isLarge
 
 #void glTexParameterfv(GLenum target, GLenum pname, GLfloat *params)
 glTexParameterfv
@@ -255,6 +257,7 @@
 #void glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)
 glTexSubImage2D
 	len pixels pixelDataSize(self, width, height, format, type, 0)
+        var_flag pixels isLarge
 	
 #void glUniform1fv(GLint location, GLsizei count, GLfloat *v)
 glUniform1fv
@@ -333,20 +336,23 @@
 
 #void glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLvoid *pixels)
 glTexImage3DOES
-	len pixels pixelDataSize3D(self, width, height, depth, format, type, 0)	
-	var_flag pixels nullAllowed
+	len pixels pixelDataSize3D(self, width, height, depth, format, type, 0)
+	var_flag pixels nullAllowed isLarge
 
 #void glTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLvoid *pixels)
 glTexSubImage3DOES
 	len pixels pixelDataSize3D(self, width, height, depth, format, type, 0)	
+        var_flag pixels isLarge
 
 #void glCompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLvoid *data)
 glCompressedTexImage3DOES
 	len data imageSize
+        var_flag data isLarge
 
 #void glCompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, GLvoid *data)
 glCompressedTexSubImage3DOES
 	len data imageSize
+        var_flag data isLarge
 
 #void glDeleteVertexArraysOES(GLsizei n, GLuint *arrays)
 glDeleteVertexArraysOES
diff --git a/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.h b/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.h
index db36286..57ee399 100644
--- a/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.h
+++ b/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.h
@@ -39,8 +39,7 @@
     bool valid() { return m_sock >= 0; }
     int recv(void *buf, size_t len);
 
-private:
-    int writeFully(const void *buf, size_t len);
+    virtual int writeFully(const void *buf, size_t len);
 
 private:
     int m_sock;
diff --git a/tools/emulator/opengl/system/egl/ClientAPIExts.cpp b/tools/emulator/opengl/system/egl/ClientAPIExts.cpp
index 888c231..5e81afe 100644
--- a/tools/emulator/opengl/system/egl/ClientAPIExts.cpp
+++ b/tools/emulator/opengl/system/egl/ClientAPIExts.cpp
@@ -129,7 +129,7 @@
 #define API_ENTRY_RET(rtype,fname,params,args) \
     API_ENTRY(fname,params,args)
 
-static struct _client_ext_funcs {
+static const struct _client_ext_funcs {
     const char *fname;
     void* proc;
 } s_client_ext_funcs[] = {
diff --git a/tools/emulator/opengl/system/egl/ClientAPIExts.in b/tools/emulator/opengl/system/egl/ClientAPIExts.in
index c3162eb..5850701 100644
--- a/tools/emulator/opengl/system/egl/ClientAPIExts.in
+++ b/tools/emulator/opengl/system/egl/ClientAPIExts.in
@@ -2,7 +2,7 @@
 // Each extension function should have one of the following
 // macro definitions:
 //    API_ENTRY(funcname, paramlist, arglist)
-//  -or- (in case funciton has return value)
+//  -or- (if the function has a return value)
 //    API_ENTRY_RET(return_type,funcname, paramlist, arglist)
 //
 API_ENTRY(glEGLImageTargetTexture2DOES,
diff --git a/tools/emulator/opengl/system/egl/eglDisplay.cpp b/tools/emulator/opengl/system/egl/eglDisplay.cpp
index 78025b1..7beeb8e 100644
--- a/tools/emulator/opengl/system/egl/eglDisplay.cpp
+++ b/tools/emulator/opengl/system/egl/eglDisplay.cpp
@@ -19,17 +19,17 @@
 
 static const int systemEGLVersionMajor = 1;
 static const int systemEGLVersionMinor = 4;
-static const char *systemEGLVendor = "Google Android emulator";
+static const char systemEGLVendor[] = "Google Android emulator";
 
 // list of extensions supported by this EGL implementation
 //  NOTE that each extension name should be suffixed with space
-static const char *systemStaticEGLExtensions =
+static const char systemStaticEGLExtensions[] =
             "EGL_ANDROID_image_native_buffer ";
 
 // list of extensions supported by this EGL implementation only if supported
 // on the host implementation.
 //  NOTE that each extension name should be suffixed with space
-static const char *systemDynamicEGLExtensions =
+static const char systemDynamicEGLExtensions[] =
             "EGL_KHR_image_base "
             "EGL_KHR_gl_texture_2d_image ";
 
@@ -70,6 +70,11 @@
     pthread_mutex_init(&m_lock, NULL);
 }
 
+eglDisplay::~eglDisplay()
+{
+    pthread_mutex_destroy(&m_lock);
+}
+
 bool eglDisplay::initialize(EGLClient_eglInterface *eglIface)
 {
     pthread_mutex_lock(&m_lock);
diff --git a/tools/emulator/opengl/system/egl/eglDisplay.h b/tools/emulator/opengl/system/egl/eglDisplay.h
index 934c699..9d979d9 100644
--- a/tools/emulator/opengl/system/egl/eglDisplay.h
+++ b/tools/emulator/opengl/system/egl/eglDisplay.h
@@ -33,6 +33,7 @@
 {
 public:
     eglDisplay();
+    ~eglDisplay();
 
     bool initialize(EGLClient_eglInterface *eglIface);
     void terminate();
diff --git a/tools/emulator/opengl/system/egl/egl_ftable.h b/tools/emulator/opengl/system/egl/egl_ftable.h
index ee40585..2c9d19a 100644
--- a/tools/emulator/opengl/system/egl/egl_ftable.h
+++ b/tools/emulator/opengl/system/egl/egl_ftable.h
@@ -13,7 +13,7 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-static struct _egl_funcs_by_name {
+static const struct _egl_funcs_by_name {
     const char *name;
     void *proc;
 } egl_funcs_by_name[] = {
@@ -63,4 +63,4 @@
     {"eglSetSwapRectangleANDROID", (void *)eglSetSwapRectangleANDROID}
 };
 
-static int egl_num_funcs = sizeof(egl_funcs_by_name) / sizeof(struct _egl_funcs_by_name);
+static const int egl_num_funcs = sizeof(egl_funcs_by_name) / sizeof(struct _egl_funcs_by_name);
diff --git a/tools/emulator/opengl/system/gralloc/gralloc.cpp b/tools/emulator/opengl/system/gralloc/gralloc.cpp
index 9c3df97..b27eaa3 100644
--- a/tools/emulator/opengl/system/gralloc/gralloc.cpp
+++ b/tools/emulator/opengl/system/gralloc/gralloc.cpp
@@ -31,6 +31,21 @@
 #include <cutils/log.h>
 #include <cutils/properties.h>
 
+/* Set to 1 or 2 to enable debug traces */
+#define DEBUG  0
+
+#if DEBUG >= 1
+#  define D(...)   LOGD(__VA_ARGS__)
+#else
+#  define D(...)   ((void)0)
+#endif
+
+#if DEBUG >= 2
+#  define DD(...)  LOGD(__VA_ARGS__)
+#else
+#  define DD(...)  ((void)0)
+#endif
+
 #define DBG_FUNC DBG("%s\n", __FUNCTION__)
 //
 // our private gralloc module structure
@@ -115,7 +130,7 @@
                          int w, int h, int format, int usage,
                          buffer_handle_t* pHandle, int* pStride)
 {
-    LOGD("gralloc_alloc w=%d h=%d usage=0x%x\n", w, h, usage);
+    D("gralloc_alloc w=%d h=%d usage=0x%x\n", w, h, usage);
 
     gralloc_device_t *grdev = (gralloc_device_t *)dev;
     if (!grdev || !pHandle || !pStride)
@@ -182,7 +197,7 @@
         *pStride = bpr / bpp;
     }
 
-    LOGD("gralloc_alloc ashmem_size=%d, tid %d\n", ashmem_size, gettid());
+    D("gralloc_alloc ashmem_size=%d, tid %d\n", ashmem_size, gettid());
 
     //
     // Allocate space in ashmem if needed
@@ -194,7 +209,7 @@
 
         fd = ashmem_create_region("gralloc-buffer", ashmem_size);
         if (fd < 0) {
-            LOGE("gralloc_alloc failed to create ashmem region err=%d\n", errno);
+            LOGE("gralloc_alloc failed to create ashmem region: %s\n", strerror(errno));
             return -errno;
         }
     }
@@ -224,7 +239,7 @@
         DEFINE_HOST_CONNECTION;
         if (hostCon && rcEnc) {
             cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat);
-            LOGD("Created host ColorBuffer 0x%x\n", cb->hostHandle);
+            D("Created host ColorBuffer 0x%x\n", cb->hostHandle);
         }
 
         if (!cb->hostHandle) {
@@ -264,7 +279,7 @@
 
     if (cb->hostHandle != 0) {
         DEFINE_AND_VALIDATE_HOST_CONNECTION;
-
+        D("Destroying host ColorBuffer 0x%x\n", cb->hostHandle);
         rcEnc->rcDestroyColorBuffer(rcEnc, cb->hostHandle);
     }
 
@@ -370,7 +385,7 @@
     DEFINE_AND_VALIDATE_HOST_CONNECTION;
 
     // send request to host
-    // XXX - should be implemented
+    // TODO: XXX - should be implemented
     //rcEnc->rc_XXX
 
     return 0;
@@ -399,9 +414,7 @@
 {
     fb_device_t *fbdev = (fb_device_t *)dev;
 
-    if (fbdev) {
-        delete fbdev;
-    }
+    delete fbdev;
 
     return 0;
 }
@@ -418,11 +431,12 @@
         return sFallback->registerBuffer(sFallback, handle);
     }
 
+    D("gralloc_register_buffer(%p) called", handle);
 
     private_module_t *gr = (private_module_t *)module;
     cb_handle_t *cb = (cb_handle_t *)handle;
     if (!gr || !cb_handle_t::validate(cb)) {
-        ERR("gralloc_register_buffer: invalid buffer");
+        ERR("gralloc_register_buffer(%p): invalid buffer", cb);
         return -EINVAL;
     }
 
@@ -434,7 +448,7 @@
         void *vaddr;
         int err = map_buffer(cb, &vaddr);
         if (err) {
-            ERR("gralloc_register_buffer: map failed");
+            ERR("gralloc_register_buffer(%p): map failed: %s", cb, strerror(-err));
             return -err;
         }
         cb->mappedPid = getpid();
@@ -453,7 +467,7 @@
     private_module_t *gr = (private_module_t *)module;
     cb_handle_t *cb = (cb_handle_t *)handle;
     if (!gr || !cb_handle_t::validate(cb)) {
-        ERR("gralloc_unregister_buffer: invalid buffer");
+        ERR("gralloc_unregister_buffer(%p): invalid buffer", cb);
         return -EINVAL;
     }
 
@@ -465,13 +479,15 @@
         void *vaddr;
         int err = munmap((void *)cb->ashmemBase, cb->ashmemSize);
         if (err) {
-            ERR("gralloc_unregister_buffer: unmap failed");
+            ERR("gralloc_unregister_buffer(%p): unmap failed", cb);
             return -EINVAL;
         }
         cb->ashmemBase = NULL;
         cb->mappedPid = 0;
     }
 
+    D("gralloc_unregister_buffer(%p) done\n", cb);
+
     return 0;
 }
 
@@ -640,7 +656,7 @@
 {
     int status = -EINVAL;
 
-    LOGD("gralloc_device_open %s\n", name);
+    D("gralloc_device_open %s\n", name);
 
     pthread_once( &sFallbackOnce, fallback_init );
     if (sFallback != NULL) {
@@ -689,16 +705,21 @@
         //
         // Query the host for Framebuffer attributes
         //
-        LOGD("gralloc: query Frabuffer attribs\n");
+        D("gralloc: query Frabuffer attribs\n");
         EGLint width = rcEnc->rcGetFBParam(rcEnc, FB_WIDTH);
-        LOGD("gralloc: width=%d\n", width);
+        D("gralloc: width=%d\n", width);
         EGLint height = rcEnc->rcGetFBParam(rcEnc, FB_HEIGHT);
-        LOGD("gralloc: height=%d\n", height);
+        D("gralloc: height=%d\n", height);
         EGLint xdpi = rcEnc->rcGetFBParam(rcEnc, FB_XDPI);
+        D("gralloc: xdpi=%d\n", xdpi);
         EGLint ydpi = rcEnc->rcGetFBParam(rcEnc, FB_YDPI);
+        D("gralloc: ydpi=%d\n", ydpi);
         EGLint fps = rcEnc->rcGetFBParam(rcEnc, FB_FPS);
+        D("gralloc: fps=%d\n", fps);
         EGLint min_si = rcEnc->rcGetFBParam(rcEnc, FB_MIN_SWAP_INTERVAL);
+        D("gralloc: min_swap=%d\n", min_si);
         EGLint max_si = rcEnc->rcGetFBParam(rcEnc, FB_MAX_SWAP_INTERVAL);
+        D("gralloc: max_swap=%d\n", max_si);
 
         //
         // Allocate memory for the framebuffer device
diff --git a/tools/emulator/opengl/system/renderControl_enc/renderControl.attrib b/tools/emulator/opengl/system/renderControl_enc/renderControl.attrib
index c51ae0e..8b9972f 100644
--- a/tools/emulator/opengl/system/renderControl_enc/renderControl.attrib
+++ b/tools/emulator/opengl/system/renderControl_enc/renderControl.attrib
@@ -26,10 +26,10 @@
 
 rcChooseConfig
     dir attribs in
-	len attribs attribs_size
-	dir configs out
+    len attribs attribs_size
+    dir configs out
     var_flag configs nullAllowed
-	len configs configs_size*sizeof(uint32_t)
+    len configs configs_size*sizeof(uint32_t)
 
 rcReadColorBuffer
     dir pixels out
@@ -38,3 +38,4 @@
 rcUpdateColorBuffer
     dir pixels in
     len pixels (((glUtilsPixelBitSize(format, type) * width) >> 3) * height)
+    var_flag pixels isLarge
diff --git a/tools/emulator/skins/WVGA800/hardware.ini b/tools/emulator/skins/WVGA800/hardware.ini
index 19e3b35..96dee4f 100644
--- a/tools/emulator/skins/WVGA800/hardware.ini
+++ b/tools/emulator/skins/WVGA800/hardware.ini
@@ -1,4 +1,4 @@
 # skin-specific hardware values
 hw.lcd.density=240
 vm.heapSize=24
-hw.ramSize=256
\ No newline at end of file
+hw.ramSize=512
\ No newline at end of file
diff --git a/tools/emulator/skins/WVGA854/hardware.ini b/tools/emulator/skins/WVGA854/hardware.ini
index 9434288..6ac3d82 100644
--- a/tools/emulator/skins/WVGA854/hardware.ini
+++ b/tools/emulator/skins/WVGA854/hardware.ini
@@ -1,4 +1,4 @@
 # skin-specific hardware values
 hw.lcd.density=240
 vm.heapSize=24
-hw.ramSize=256
+hw.ramSize=512
diff --git a/tools/emulator/skins/WXGA/arrow_down.png b/tools/emulator/skins/WXGA720/arrow_down.png
similarity index 100%
rename from tools/emulator/skins/WXGA/arrow_down.png
rename to tools/emulator/skins/WXGA720/arrow_down.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/arrow_left.png b/tools/emulator/skins/WXGA720/arrow_left.png
similarity index 100%
rename from tools/emulator/skins/WXGA/arrow_left.png
rename to tools/emulator/skins/WXGA720/arrow_left.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/arrow_right.png b/tools/emulator/skins/WXGA720/arrow_right.png
similarity index 100%
rename from tools/emulator/skins/WXGA/arrow_right.png
rename to tools/emulator/skins/WXGA720/arrow_right.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/arrow_up.png b/tools/emulator/skins/WXGA720/arrow_up.png
similarity index 100%
rename from tools/emulator/skins/WXGA/arrow_up.png
rename to tools/emulator/skins/WXGA720/arrow_up.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA720/background_land.png b/tools/emulator/skins/WXGA720/background_land.png
new file mode 100755
index 0000000..2aba27e
--- /dev/null
+++ b/tools/emulator/skins/WXGA720/background_land.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA720/background_port.png b/tools/emulator/skins/WXGA720/background_port.png
new file mode 100755
index 0000000..9561ca8
--- /dev/null
+++ b/tools/emulator/skins/WXGA720/background_port.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/button.png b/tools/emulator/skins/WXGA720/button.png
similarity index 100%
rename from tools/emulator/skins/WXGA/button.png
rename to tools/emulator/skins/WXGA720/button.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/controls.png b/tools/emulator/skins/WXGA720/controls.png
similarity index 100%
rename from tools/emulator/skins/WXGA/controls.png
rename to tools/emulator/skins/WXGA720/controls.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA720/hardware.ini b/tools/emulator/skins/WXGA720/hardware.ini
new file mode 100755
index 0000000..3be263c
--- /dev/null
+++ b/tools/emulator/skins/WXGA720/hardware.ini
@@ -0,0 +1,8 @@
+# skin-specific hardware values
+hw.lcd.density=320
+vm.heapSize=48
+hw.ramSize=1024
+hw.keyboard.lid=no
+hw.mainKeys=no
+
+
diff --git a/tools/emulator/skins/WXGA/key.png b/tools/emulator/skins/WXGA720/key.png
similarity index 100%
rename from tools/emulator/skins/WXGA/key.png
rename to tools/emulator/skins/WXGA720/key.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/keyboard.png b/tools/emulator/skins/WXGA720/keyboard.png
similarity index 100%
rename from tools/emulator/skins/WXGA/keyboard.png
rename to tools/emulator/skins/WXGA720/keyboard.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA720/layout b/tools/emulator/skins/WXGA720/layout
new file mode 100755
index 0000000..8332bdc
--- /dev/null
+++ b/tools/emulator/skins/WXGA720/layout
@@ -0,0 +1,88 @@
+parts {
+    portrait {
+        background {
+            image   background_port.png
+        }
+    }
+    landscape {
+        background {
+            image   background_land.png
+        }
+    }
+
+    device {
+        display {
+            width   1280
+            height  720
+            x       0
+            y       0
+        }
+    }
+    
+}
+
+layouts {
+
+    landscape {
+        width     1333
+        height    775
+        color     0xe0e0e0
+        event     EV_SW:0:1
+
+        part1 {
+            name    portrait
+            x       1400
+            y       0
+        }
+
+        part2 {
+            name    landscape
+            x       0
+            y       0
+        }
+
+        part3 {
+            name      device
+            x         26
+            y         29
+        }
+    }
+
+    portrait {
+        width     773
+        height    1334
+        color     0xe0e0e0
+        event     EV_SW:0:0
+
+        dpad-rotation 3
+        
+        part1 {
+            name    portrait
+            x       0
+            y       0
+        }
+
+        part2 {
+            name    landscape
+            x       1400
+            y       0
+        }
+
+        part3 {
+            name    device
+            x       27
+            y       1307
+            rotation  3
+        }
+    }
+
+}
+
+keyboard {
+    charmap qwerty2
+}
+
+network {
+    speed  full
+    delay  none
+}
diff --git a/tools/emulator/skins/WXGA/select.png b/tools/emulator/skins/WXGA720/select.png
similarity index 100%
rename from tools/emulator/skins/WXGA/select.png
rename to tools/emulator/skins/WXGA720/select.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/spacebar.png b/tools/emulator/skins/WXGA720/spacebar.png
similarity index 100%
rename from tools/emulator/skins/WXGA/spacebar.png
rename to tools/emulator/skins/WXGA720/spacebar.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/arrow_down.png b/tools/emulator/skins/WXGA800/arrow_down.png
similarity index 100%
copy from tools/emulator/skins/WXGA/arrow_down.png
copy to tools/emulator/skins/WXGA800/arrow_down.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/arrow_left.png b/tools/emulator/skins/WXGA800/arrow_left.png
similarity index 100%
copy from tools/emulator/skins/WXGA/arrow_left.png
copy to tools/emulator/skins/WXGA800/arrow_left.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/arrow_right.png b/tools/emulator/skins/WXGA800/arrow_right.png
similarity index 100%
copy from tools/emulator/skins/WXGA/arrow_right.png
copy to tools/emulator/skins/WXGA800/arrow_right.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/arrow_up.png b/tools/emulator/skins/WXGA800/arrow_up.png
similarity index 100%
copy from tools/emulator/skins/WXGA/arrow_up.png
copy to tools/emulator/skins/WXGA800/arrow_up.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/background_land.png b/tools/emulator/skins/WXGA800/background_land.png
similarity index 100%
rename from tools/emulator/skins/WXGA/background_land.png
rename to tools/emulator/skins/WXGA800/background_land.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/background_port.png b/tools/emulator/skins/WXGA800/background_port.png
similarity index 100%
rename from tools/emulator/skins/WXGA/background_port.png
rename to tools/emulator/skins/WXGA800/background_port.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/button.png b/tools/emulator/skins/WXGA800/button.png
similarity index 100%
copy from tools/emulator/skins/WXGA/button.png
copy to tools/emulator/skins/WXGA800/button.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/controls.png b/tools/emulator/skins/WXGA800/controls.png
similarity index 100%
copy from tools/emulator/skins/WXGA/controls.png
copy to tools/emulator/skins/WXGA800/controls.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/hardware.ini b/tools/emulator/skins/WXGA800/hardware.ini
similarity index 84%
rename from tools/emulator/skins/WXGA/hardware.ini
rename to tools/emulator/skins/WXGA800/hardware.ini
index c777f9e..81eac11 100755
--- a/tools/emulator/skins/WXGA/hardware.ini
+++ b/tools/emulator/skins/WXGA800/hardware.ini
@@ -1,6 +1,6 @@
 # skin-specific hardware values
 hw.lcd.density=160
 vm.heapSize=48
-hw.ramSize=512
+hw.ramSize=1024
 hw.keyboard.lid=no
 
diff --git a/tools/emulator/skins/WXGA/key.png b/tools/emulator/skins/WXGA800/key.png
similarity index 100%
copy from tools/emulator/skins/WXGA/key.png
copy to tools/emulator/skins/WXGA800/key.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/keyboard.png b/tools/emulator/skins/WXGA800/keyboard.png
similarity index 100%
copy from tools/emulator/skins/WXGA/keyboard.png
copy to tools/emulator/skins/WXGA800/keyboard.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/layout b/tools/emulator/skins/WXGA800/layout
similarity index 100%
rename from tools/emulator/skins/WXGA/layout
rename to tools/emulator/skins/WXGA800/layout
diff --git a/tools/emulator/skins/WXGA/select.png b/tools/emulator/skins/WXGA800/select.png
similarity index 100%
copy from tools/emulator/skins/WXGA/select.png
copy to tools/emulator/skins/WXGA800/select.png
Binary files differ
diff --git a/tools/emulator/skins/WXGA/spacebar.png b/tools/emulator/skins/WXGA800/spacebar.png
similarity index 100%
copy from tools/emulator/skins/WXGA/spacebar.png
copy to tools/emulator/skins/WXGA800/spacebar.png
Binary files differ
diff --git a/tools/emulator/system/camera/Converters.h b/tools/emulator/system/camera/Converters.h
index ab00711..13e2a85 100755
--- a/tools/emulator/system/camera/Converters.h
+++ b/tools/emulator/system/camera/Converters.h
@@ -17,7 +17,7 @@
 #ifndef HW_EMULATOR_CAMERA_CONVERTERS_H
 #define HW_EMULATOR_CAMERA_CONVERTERS_H
 
-#include <sys/endian.h>
+#include <endian.h>
 
 #ifndef __BYTE_ORDER
 #error "could not determine byte order"